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

Add dns and ntp servers flag to machine and partition creation #266

Merged
merged 7 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
16 changes: 14 additions & 2 deletions cmd/firewall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ var (
SSHPubKeys: []string{"sshpubkey"},
Succeeded: pointer.Pointer(true),
UserData: "---userdata---",
DNSServers: []*models.MetalDNSServer{{IP: pointer.Pointer("8.8.8.8")}},
NtpServers: []*models.MetalNTPServer{{Address: pointer.Pointer("1.pool.ntp.org")}},
},
Bios: &models.V1MachineBIOS{
Date: pointer.Pointer("biosdata"),
Expand Down Expand Up @@ -275,13 +277,21 @@ ID AGE HOSTNAME PROJECT NETWORKS IPS PARTITION
name: "create",
cmd: func(want *models.V1FirewallResponse) []string {
var (
ips []string
networks []string
ips []string
networks []string
dnsServers []string
ntpservers []string
)
for _, s := range want.Allocation.Networks {
ips = append(ips, s.Ips...)
networks = append(networks, *s.Networkid+":noauto")
}
for _, dns := range want.Allocation.DNSServers {
dnsServers = append(dnsServers, *dns.IP)
}
for _, ntp := range want.Allocation.NtpServers {
ntpservers = append(ntpservers, *ntp.Address)
}

args := []string{"firewall", "create",
"--id", *want.ID,
Expand All @@ -299,6 +309,8 @@ ID AGE HOSTNAME PROJECT NETWORKS IPS PARTITION
"--tags", strings.Join(want.Tags, ","),
"--userdata", want.Allocation.UserData,
"--firewall-rules-file", "",
"--dnsservers", strings.Join(dnsServers, ","),
"--ntpservers", strings.Join(ntpservers, ","),
}
assertExhaustiveArgs(t, args, commonExcludedFileArgs()...)
return args
Expand Down
33 changes: 32 additions & 1 deletion cmd/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,8 @@ If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picke
cmd.Flags().StringSlice("tags", []string{}, "tags to add to the "+name+", use it like: --tags \"tag1,tag2\" or --tags \"tag3\".")
cmd.Flags().StringP("userdata", "", "", `cloud-init.io compatible userdata. [optional]
Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg".`)
cmd.Flags().StringSlice("dnsservers", []string{}, "dns servers to add to the machine or firewall. [optional]")
cmd.Flags().StringSlice("ntpservers", []string{}, "ntp servers to add to the machine or firewall. [optional]")

switch name {
case "machine":
Expand Down Expand Up @@ -637,6 +639,8 @@ func machineResponseToCreate(r *models.V1MachineResponse) *models.V1MachineAlloc
ips []string
networks []*models.V1MachineAllocationNetwork
allocation = pointer.SafeDeref(r.Allocation)
dnsServers []*models.MetalDNSServer
ntpServers []*models.MetalNTPServer
)
for _, s := range allocation.Networks {
ips = append(ips, s.Ips...)
Expand All @@ -646,6 +650,14 @@ func machineResponseToCreate(r *models.V1MachineResponse) *models.V1MachineAlloc
})
}

for _, s := range allocation.DNSServers {
dnsServers = append(dnsServers, &models.MetalDNSServer{IP: s.IP})
}

for _, s := range allocation.NtpServers {
ntpServers = append(ntpServers, &models.MetalNTPServer{Address: s.Address})
}

return &models.V1MachineAllocateRequest{
Description: allocation.Description,
Filesystemlayoutid: pointer.SafeDeref(pointer.SafeDeref(allocation.Filesystemlayout).ID),
Expand All @@ -661,6 +673,8 @@ func machineResponseToCreate(r *models.V1MachineResponse) *models.V1MachineAlloc
Tags: r.Tags,
UserData: base64.StdEncoding.EncodeToString([]byte(allocation.UserData)),
UUID: pointer.SafeDeref(r.ID),
DNSServers: dnsServers,
NtpServers: ntpServers,
}
}

Expand All @@ -684,7 +698,15 @@ func (c *machineCmd) createRequestFromCLI() (*models.V1MachineAllocateRequest, e
}

func machineCreateRequest() (*models.V1MachineAllocateRequest, error) {
var (
keys []string
dnsServers []*models.MetalDNSServer
ntpServers []*models.MetalNTPServer
)

sshPublicKeyArgument := viper.GetString("sshpublickey")
dnsServersArgument := viper.GetStringSlice("dnsservers")
ntpServersArgument := viper.GetStringSlice("ntpservers")

if strings.HasPrefix(sshPublicKeyArgument, "@") {
var err error
Expand All @@ -706,7 +728,6 @@ func machineCreateRequest() (*models.V1MachineAllocateRequest, error) {
}
}

var keys []string
if sshPublicKeyArgument != "" {
keys = append(keys, sshPublicKeyArgument)
}
Expand All @@ -729,6 +750,14 @@ func machineCreateRequest() (*models.V1MachineAllocateRequest, error) {
return nil, err
}

for _, s := range dnsServersArgument {
dnsServers = append(dnsServers, &models.MetalDNSServer{IP: pointer.Pointer(s)})
}

for _, s := range ntpServersArgument {
ntpServers = append(ntpServers, &models.MetalNTPServer{Address: pointer.Pointer(s)})
}

mcr := &models.V1MachineAllocateRequest{
Description: viper.GetString("description"),
Partitionid: pointer.Pointer(viper.GetString("partition")),
Expand All @@ -743,6 +772,8 @@ func machineCreateRequest() (*models.V1MachineAllocateRequest, error) {
UserData: userDataArgument,
Networks: networks,
Ips: viper.GetStringSlice("ips"),
DNSServers: dnsServers,
NtpServers: ntpServers,
}

if viper.IsSet("filesystemlayout") {
Expand Down
40 changes: 26 additions & 14 deletions cmd/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ var (
SSHPubKeys: []string{"sshpubkey"},
Succeeded: pointer.Pointer(true),
UserData: "---userdata---",
DNSServers: []*models.MetalDNSServer{{IP: pointer.Pointer("8.8.8.8")}},
NtpServers: []*models.MetalNTPServer{{Address: pointer.Pointer("1.pool.ntp.org")}},
},
Bios: &models.V1MachineBIOS{
Date: pointer.Pointer("biosdata"),
Expand Down Expand Up @@ -369,22 +371,22 @@ func Test_MachineCmd_SingleResult(t *testing.T) {
},
want: machine1,
wantTable: pointer.Pointer(`
ID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION RACK
1 Phoned Home 7d 14d machine-hostname-1 project-1 1 debian-name 1 rack-1
`),
ID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION RACK
1 Phoned Home 7d 14d machine-hostname-1 project-1 1 debian-name 1 rack-1
`),
wantWideTable: pointer.Pointer(`
ID LAST EVENT WHEN AGE DESCRIPTION NAME HOSTNAME PROJECT IPS SIZE IMAGE PARTITION RACK STARTED TAGS LOCK/RESERVE
1 Phoned Home 7d 14d machine allocation 1 machine-1 machine-hostname-1 project-1 1.1.1.1 1 debian-name 1 rack-1 2022-05-05T01:02:03Z a
`),
ID LAST EVENT WHEN AGE DESCRIPTION NAME HOSTNAME PROJECT IPS SIZE IMAGE PARTITION RACK STARTED TAGS LOCK/RESERVE
1 Phoned Home 7d 14d machine allocation 1 machine-1 machine-hostname-1 project-1 1.1.1.1 1 debian-name 1 rack-1 2022-05-05T01:02:03Z a
`),
template: pointer.Pointer("{{ .id }} {{ .name }}"),
wantTemplate: pointer.Pointer(`
1 machine-1
`),
1 machine-1
`),
wantMarkdown: pointer.Pointer(`
| ID | | LAST EVENT | WHEN | AGE | HOSTNAME | PROJECT | SIZE | IMAGE | PARTITION | RACK |
|----|--|-------------|------|-----|--------------------|-----------|------|-------------|-----------|--------|
| 1 | | Phoned Home | 7d | 14d | machine-hostname-1 | project-1 | 1 | debian-name | 1 | rack-1 |
`),
| ID | | LAST EVENT | WHEN | AGE | HOSTNAME | PROJECT | SIZE | IMAGE | PARTITION | RACK |
|----|--|-------------|------|-----|--------------------|-----------|------|-------------|-----------|--------|
| 1 | | Phoned Home | 7d | 14d | machine-hostname-1 | project-1 | 1 | debian-name | 1 | rack-1 |
`),
},
{
name: "delete",
Expand All @@ -404,13 +406,21 @@ ID LAST EVENT WHEN AGE DESCRIPTION NAME HOSTNAME
name: "create",
cmd: func(want *models.V1MachineResponse) []string {
var (
ips []string
networks []string
ips []string
networks []string
dnsServers []string
ntpservers []string
)
for _, s := range want.Allocation.Networks {
ips = append(ips, s.Ips...)
networks = append(networks, *s.Networkid+":noauto")
}
for _, dns := range want.Allocation.DNSServers {
dnsServers = append(dnsServers, *dns.IP)
}
for _, ntp := range want.Allocation.NtpServers {
ntpservers = append(ntpservers, *ntp.Address)
}

args := []string{"machine", "create",
"--id", *want.ID,
Expand All @@ -427,6 +437,8 @@ ID LAST EVENT WHEN AGE DESCRIPTION NAME HOSTNAME
"--sshpublickey", pointer.FirstOrZero(want.Allocation.SSHPubKeys),
"--tags", strings.Join(want.Tags, ","),
"--userdata", want.Allocation.UserData,
"--dnsservers", strings.Join(dnsServers, ","),
"--ntpservers", strings.Join(ntpservers, ","),
}
assertExhaustiveArgs(t, args, commonExcludedFileArgs()...)
return args
Expand Down
76 changes: 54 additions & 22 deletions cmd/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,16 @@ func newPartitionCmd(c *config) *cobra.Command {
}

cmdsConfig := &genericcli.CmdsConfig[*models.V1PartitionCreateRequest, *models.V1PartitionUpdateRequest, *models.V1PartitionResponse]{
BinaryName: binaryName,
GenericCLI: genericcli.NewGenericCLI[*models.V1PartitionCreateRequest, *models.V1PartitionUpdateRequest, *models.V1PartitionResponse](w).WithFS(c.fs),
Singular: "partition",
Plural: "partitions",
Description: "a partition is a failure domain in the data center.",
ValidArgsFn: c.comp.PartitionListCompletion,
Sorter: sorters.PartitionSorter(),
DescribePrinter: func() printers.Printer { return c.describePrinter },
ListPrinter: func() printers.Printer { return c.listPrinter },
CreateRequestFromCLI: func() (*models.V1PartitionCreateRequest, error) {
return &models.V1PartitionCreateRequest{
ID: pointer.Pointer(viper.GetString("id")),
Description: viper.GetString("description"),
Name: viper.GetString("name"),
Mgmtserviceaddress: viper.GetString("mgmtserver"),
Bootconfig: &models.V1PartitionBootConfiguration{
Commandline: viper.GetString("cmdline"),
Imageurl: viper.GetString("imageurl"),
Kernelurl: viper.GetString("kernelurl"),
},
}, nil
},
BinaryName: binaryName,
GenericCLI: genericcli.NewGenericCLI[*models.V1PartitionCreateRequest, *models.V1PartitionUpdateRequest, *models.V1PartitionResponse](w).WithFS(c.fs),
Singular: "partition",
Plural: "partitions",
Description: "a partition is a failure domain in the data center.",
ValidArgsFn: c.comp.PartitionListCompletion,
Sorter: sorters.PartitionSorter(),
DescribePrinter: func() printers.Printer { return c.describePrinter },
ListPrinter: func() printers.Printer { return c.listPrinter },
CreateRequestFromCLI: w.createRequestFromCLI,
CreateCmdMutateFn: func(cmd *cobra.Command) {
cmd.Flags().StringP("id", "", "", "ID of the partition. [required]")
cmd.Flags().StringP("name", "n", "", "Name of the partition. [optional]")
Expand All @@ -56,6 +44,8 @@ func newPartitionCmd(c *config) *cobra.Command {
cmd.Flags().StringP("cmdline", "", "", "kernel commandline for the metal-hammer in the partition. [required]")
cmd.Flags().StringP("imageurl", "", "", "initrd for the metal-hammer in the partition. [required]")
cmd.Flags().StringP("kernelurl", "", "", "kernel url for the metal-hammer in the partition. [required]")
cmd.Flags().StringP("dnsservers", "", "", "dns servers for the machines and firewalls in the partition. [optional]")
cmd.Flags().StringP("ntpservers", "", "", "ntp servers for the machines and firewalls in the partition. [optional]")
},
}

Expand Down Expand Up @@ -145,6 +135,8 @@ func partitionResponseToCreate(r *models.V1PartitionResponse) *models.V1Partitio
Mgmtserviceaddress: r.Mgmtserviceaddress,
Name: r.Name,
Privatenetworkprefixlength: r.Privatenetworkprefixlength,
DNSServers: r.DNSServers,
NtpServers: r.NtpServers,
}
}

Expand Down Expand Up @@ -188,3 +180,43 @@ func (c *partitionCmd) partitionCapacity() error {

return c.listPrinter.Print(resp.Payload)
}

func (c *partitionCmd) createRequestFromCLI() (*models.V1PartitionCreateRequest, error) {
pcr := partitionCreateRequest()

return pcr, nil
}

func partitionCreateRequest() *models.V1PartitionCreateRequest {
Gerrit91 marked this conversation as resolved.
Show resolved Hide resolved
var (
dnsServers []*models.MetalDNSServer
ntpServers []*models.MetalNTPServer
)

dnsServersArgument := viper.GetStringSlice("dnsservers")
ntpServersArgument := viper.GetStringSlice("ntpservers")

for _, s := range dnsServersArgument {
dnsServers = append(dnsServers, &models.MetalDNSServer{IP: pointer.Pointer(s)})
}

for _, s := range ntpServersArgument {
ntpServers = append(ntpServers, &models.MetalNTPServer{Address: pointer.Pointer(s)})
}

pcr := &models.V1PartitionCreateRequest{
ID: pointer.Pointer(viper.GetString("id")),
Description: viper.GetString("description"),
Name: viper.GetString("name"),
Mgmtserviceaddress: viper.GetString("mgmtserver"),
Bootconfig: &models.V1PartitionBootConfiguration{
Commandline: viper.GetString("cmdline"),
Imageurl: viper.GetString("imageurl"),
Kernelurl: viper.GetString("kernelurl"),
},
DNSServers: dnsServers,
NtpServers: ntpServers,
}

return pcr
}
15 changes: 15 additions & 0 deletions cmd/partition_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"strings"
"testing"

"github.com/metal-stack/metal-go/api/client/partition"
Expand Down Expand Up @@ -224,6 +225,18 @@ ID NAME DESCRIPTION LABELS
{
name: "create",
cmd: func(want *models.V1PartitionResponse) []string {
var (
dnsServers []string
ntpServers []string
)
for _, dns := range want.DNSServers {
dnsServers = append(dnsServers, *dns.IP)
}

for _, ntp := range want.NtpServers {
ntpServers = append(ntpServers, *ntp.Address)
}

args := []string{"partition", "create",
"--id", *want.ID,
"--name", want.Name,
Expand All @@ -232,6 +245,8 @@ ID NAME DESCRIPTION LABELS
"--kernelurl", want.Bootconfig.Kernelurl,
"--imageurl", want.Bootconfig.Imageurl,
"--mgmtserver", want.Mgmtserviceaddress,
"--dnsservers", strings.Join(dnsServers, ","),
"--ntpservers", strings.Join(ntpServers, ","),
}
assertExhaustiveArgs(t, args, commonExcludedFileArgs()...)
return args
Expand Down
2 changes: 2 additions & 0 deletions docs/metalctl_firewall_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ metalctl firewall create [flags]
```
--bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
-d, --description string Description of the firewall to create. [optional]
--dnsservers strings dns servers to add to the machine or firewall. [optional]
-f, --file string filename of the create or update request in yaml format, or - for stdin.

Example:
Expand Down Expand Up @@ -85,6 +86,7 @@ metalctl firewall create [flags]
MODE can be omitted or one of:
auto IP address is automatically acquired from the given network
noauto No automatic IP address acquisition
--ntpservers strings ntp servers to add to the machine or firewall. [optional]
-S, --partition string partition/datacenter where the firewall is created. [required, except for reserved machines]
-P, --project string Project where the firewall should belong to. [required]
-s, --size string Size of the firewall. [required, except for reserved machines]
Expand Down
2 changes: 2 additions & 0 deletions docs/metalctl_machine_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Once created the machine installation can not be modified anymore.
```
--bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
-d, --description string Description of the machine to create. [optional]
--dnsservers strings dns servers to add to the machine or firewall. [optional]
-f, --file string filename of the create or update request in yaml format, or - for stdin.

Example:
Expand All @@ -77,6 +78,7 @@ Once created the machine installation can not be modified anymore.
MODE cane be omitted or one of:
auto IP address is automatically acquired from the given network
noauto IP address for the given network must be provided via --ips
--ntpservers strings ntp servers to add to the machine or firewall. [optional]
-S, --partition string partition/datacenter where the machine is created. [required, except for reserved machines]
-P, --project string Project where the machine should belong to. [required]
-s, --size string Size of the machine. [required, except for reserved machines]
Expand Down
2 changes: 2 additions & 0 deletions docs/metalctl_partition_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ metalctl partition create [flags]
--bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
--cmdline string kernel commandline for the metal-hammer in the partition. [required]
-d, --description string Description of the partition. [required]
--dnsservers string dns servers for the machines and firewalls in the partition. [optional]
-f, --file string filename of the create or update request in yaml format, or - for stdin.

Example:
Expand All @@ -30,6 +31,7 @@ metalctl partition create [flags]
--kernelurl string kernel url for the metal-hammer in the partition. [required]
--mgmtserver string management server address in the partition. [required]
-n, --name string Name of the partition. [optional]
--ntpservers string ntp servers for the machines and firewalls in the partition. [optional]
--skip-security-prompts skips security prompt for bulk operations
--timestamps when used with --file (bulk operation): prints timestamps in-between the operations
```
Expand Down
Loading