Skip to content

Commit

Permalink
create/update/show.
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Oct 23, 2024
1 parent f1ddd2c commit 3b3d0d0
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 72 deletions.
105 changes: 78 additions & 27 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"
)

Expand All @@ -23,11 +20,12 @@ 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:"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 v3.ZoneName `cli-short:"z" cli-usage:"Private Network zone"`
Option []string `cli-usage:"DHCP network option (format: option1=\"value1 value2\")" cli-flag-multi:"true"`
}

func (c *privateNetworkCreateCmd) cmdAliases() []string { return gCreateAlias }
Expand All @@ -49,37 +47,90 @@ 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 ""
}(),
EndIP: func() net.IP {
if c.EndIP != "" {
ip := net.ParseIP(c.EndIP)
v = &ip
return net.ParseIP(c.EndIP)
}
return
return nil
}(),
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
}(),
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
}(),
}

var err error
if len(c.Option) > 0 {
opts := &v3.PrivateNetworkOptions{}
optionsMap := make(map[string][]string)

// Process each option flag
for _, opt := range c.Option {
keyValue := strings.SplitN(opt, "=", 2)
if len(keyValue) != 2 {
continue
}
key := keyValue[0]
values := strings.Split(keyValue[1], " ")
optionsMap[key] = append(optionsMap[key], values...)
}

// Process collected values
for key, values := range optionsMap {
switch key {
case "dns-servers":
for _, v := range values {
if ip := net.ParseIP(v); ip != nil {
opts.DNSServers = append(opts.DNSServers, ip)
}
}
case "ntp-servers":
for _, v := range values {
if ip := net.ParseIP(v); ip != nil {
opts.NtpServers = append(opts.NtpServers, ip)
}
}
case "routers":
for _, v := range values {
if ip := net.ParseIP(v); ip != nil {
opts.Routers = append(opts.Routers, ip)
}
}
case "domain-search":
opts.DomainSearch = values
}
}
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 @@ -88,7 +139,7 @@ func (c *privateNetworkCreateCmd) cmdRun(_ *cobra.Command, _ []string) error {
if !globalstate.Quiet {
return (&privateNetworkShowCmd{
cliCommandSettings: c.cliCommandSettings,
PrivateNetwork: *privateNetwork.ID,
PrivateNetwork: c.Name,
Zone: v3.ZoneName(c.Zone),
}).cmdRun(nil, nil)
}
Expand Down
95 changes: 74 additions & 21 deletions cmd/private_network_show.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"strings"

"github.com/davecgh/go-spew/spew"
"github.com/olekukonko/tablewriter"
"github.com/spf13/cobra"

Expand All @@ -22,7 +21,7 @@ type privateNetworkLeaseOutput struct {
IPAddress string `json:"ip_address"`
}

type privateNetworkOptions struct {
type privateNetworkOptionsOutput struct {
Routers []net.IP `json:"routers"`
DNSServers []net.IP `json:"dns-servers"`
NTPServers []net.IP `json:"ntp-servers"`
Expand All @@ -39,7 +38,7 @@ type privateNetworkShowOutput struct {
EndIP *string `json:"end_ip,omitempty"`
Netmask *string `json:"netmask,omitempty"`
Leases []privateNetworkLeaseOutput `json:"leases,omitempty"`
Options privateNetworkOptions `json:"options"`
Options privateNetworkOptionsOutput `json:"options"`
}

func (o *privateNetworkShowOutput) ToJSON() { output.JSON(o) }
Expand All @@ -59,25 +58,14 @@ func (o *privateNetworkShowOutput) ToTable() {
t.Append([]string{"Start IP", *o.StartIP})
t.Append([]string{"End IP", *o.EndIP})
t.Append([]string{"Netmask", *o.Netmask})

t.Append([]string{
"Leases", func(leases []privateNetworkLeaseOutput) string {
if len(leases) > 0 {
buf := bytes.NewBuffer(nil)
at := table.NewEmbeddedTable(buf)
at.SetHeader([]string{" "})
at.SetAlignment(tablewriter.ALIGN_LEFT)

for _, lease := range leases {
at.Append([]string{lease.Instance, lease.IPAddress})
}
at.Render()

return buf.String()
}
return "-"
}(o.Leases),
"Leases", formatLeases(o.Leases),
})
}
t.Append([]string{
"Options", formatOptions(o.Options),
})
}

type privateNetworkShowCmd struct {
Expand Down Expand Up @@ -133,14 +121,23 @@ func (c *privateNetworkShowCmd) cmdRun(_ *cobra.Command, _ []string) error {
return err
}

spew.Dump(privateNetwork)

out := privateNetworkShowOutput{
ID: privateNetwork.ID,
Zone: c.Zone,
Name: privateNetwork.Name,
Description: privateNetwork.Description,
Type: "manual",
Options: func() privateNetworkOptionsOutput {
if privateNetwork.Options == nil {
return privateNetworkOptionsOutput{}
}
return privateNetworkOptionsOutput{
Routers: privateNetwork.Options.Routers,
DNSServers: privateNetwork.Options.DNSServers,
NTPServers: privateNetwork.Options.NtpServers,
DomainSearch: privateNetwork.Options.DomainSearch,
}
}(),
}

if privateNetwork.StartIP != nil {
Expand Down Expand Up @@ -180,3 +177,59 @@ func init() {
cliCommandSettings: defaultCLICmdSettings(),
}))
}

func ipSliceToStringSlice(ips []net.IP) []string {
result := make([]string, len(ips))
for i, ip := range ips {
result[i] = ip.String()
}
return result
}

func formatLeases(leases []privateNetworkLeaseOutput) string {
if len(leases) == 0 {
return "-"
}

buf := bytes.NewBuffer(nil)
at := table.NewEmbeddedTable(buf)
at.SetHeader([]string{" "})
at.SetAlignment(tablewriter.ALIGN_LEFT)

for _, lease := range leases {
at.Append([]string{lease.Instance, lease.IPAddress})
}
at.Render()

return buf.String()
}

func formatOptions(opts privateNetworkOptionsOutput) string {
hasOptions := len(opts.Routers) > 0 || len(opts.DNSServers) > 0 ||
len(opts.NTPServers) > 0 || len(opts.DomainSearch) > 0

if !hasOptions {
return "-"
}

buf := bytes.NewBuffer(nil)
at := table.NewEmbeddedTable(buf)
at.SetHeader([]string{" "})
at.SetAlignment(tablewriter.ALIGN_LEFT)

if len(opts.Routers) > 0 {
at.Append([]string{"Routers", strings.Join(ipSliceToStringSlice(opts.Routers), ", ")})
}
if len(opts.DNSServers) > 0 {
at.Append([]string{"DNS Servers", strings.Join(ipSliceToStringSlice(opts.DNSServers), ", ")})
}
if len(opts.NTPServers) > 0 {
at.Append([]string{"NTP Servers", strings.Join(ipSliceToStringSlice(opts.NTPServers), ", ")})
}
if len(opts.DomainSearch) > 0 {
at.Append([]string{"Domain Search", strings.Join(opts.DomainSearch, ", ")})
}

at.Render()
return buf.String()
}
Loading

0 comments on commit 3b3d0d0

Please sign in to comment.