Skip to content

Commit

Permalink
Review with Simon.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit91 committed Nov 8, 2024
1 parent 5f678e1 commit 5f71f78
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 91 deletions.
45 changes: 45 additions & 0 deletions cmd/metal-api/internal/metal/machine.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package metal

import (
"errors"
"fmt"
"log/slog"
"net"
"net/netip"
"os"
"path/filepath"
"slices"
"strings"
"time"

"github.com/asaskevich/govalidator"
"github.com/dustin/go-humanize"
mn "github.com/metal-stack/metal-lib/pkg/net"
"github.com/samber/lo"
Expand Down Expand Up @@ -731,3 +734,45 @@ func (i *MachineIPMISuperUser) User() string {
func DisabledIPMISuperUser() MachineIPMISuperUser {
return MachineIPMISuperUser{}
}

func (d DNSServers) Validate() error {
if d == nil {
return nil
}

if len(d) > 3 {
return errors.New("please specify a maximum of three dns servers")
}

for _, dnsServer := range d {
_, err := netip.ParseAddr(dnsServer.IP)
if err != nil {
return fmt.Errorf("ip: %s for dns server not correct err: %w", dnsServer, err)
}
}
return nil
}

func (n NTPServers) Validate() error {
if n == nil {
return nil
}

if len(n) < 3 || len(n) > 5 {
return errors.New("please specify a minimum of 3 and a maximum of 5 ntp servers")
}

for _, ntpserver := range n {
if net.ParseIP(ntpserver.Address) != nil {
_, err := netip.ParseAddr(ntpserver.Address)
if err != nil {
return fmt.Errorf("ip: %s for ntp server not correct err: %w", ntpserver, err)
}
} else {
if !govalidator.IsDNSName(ntpserver.Address) {
return fmt.Errorf("dns name: %s for ntp server not correct", ntpserver)
}
}
}
return nil
}
56 changes: 16 additions & 40 deletions cmd/metal-api/internal/service/machine-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import (
"log/slog"
"net"
"net/http"
"net/netip"
"strconv"
"strings"
"time"

"github.com/asaskevich/govalidator"
"github.com/google/uuid"
"github.com/metal-stack/metal-api/cmd/metal-api/internal/headscale"
"github.com/metal-stack/metal-api/cmd/metal-api/internal/issues"
Expand Down Expand Up @@ -1151,29 +1149,33 @@ func createMachineAllocationSpec(ds *datastore.RethinkStore, machineRequest v1.M
if err != nil {
return nil, fmt.Errorf("partition:%s not found err:%w", partitionID, err)
}

var (
dnsServers = partition.DNSServers
ntpServers = partition.NTPServers
)
if len(machineRequest.DNSServers) != 0 {
if len(machineRequest.DNSServers) > 3 {
return nil, errors.New("please specify a maximum of three dns servers")
dnsServers = metal.DNSServers{}
for _, s := range machineRequest.DNSServers {
dnsServers = append(dnsServers, metal.DNSServer{
IP: s.IP,
})
}
dnsServers = machineRequest.DNSServers
}

if err := ValidateDNSServers(dnsServers); err != nil {
return nil, err
}

if len(machineRequest.NTPServers) != 0 {
if len(machineRequest.NTPServers) < 3 || len(machineRequest.NTPServers) > 5 {
return nil, errors.New("please specify a minimum of 3 and a maximum of 5 ntp servers")
ntpServers = []metal.NTPServer{}
for _, s := range machineRequest.NTPServers {
ntpServers = append(ntpServers, metal.NTPServer{
Address: s.Address,
})
}
ntpServers = machineRequest.NTPServers
}

if err := ValidateNTPServers(ntpServers); err != nil {
if err := dnsServers.Validate(); err != nil {
return nil, err
}

if err := ntpServers.Validate(); err != nil {
return nil, err
}

Expand Down Expand Up @@ -2512,29 +2514,3 @@ func (s machineAllocationSpec) noautoNetworkN() int {
func (s machineAllocationSpec) autoNetworkN() int {
return len(s.Networks) - s.noautoNetworkN()
}

func ValidateDNSServers(d metal.DNSServers) error {
for _, dnsServer := range d {
_, err := netip.ParseAddr(dnsServer.IP)
if err != nil {
return fmt.Errorf("ip: %s for dns server not correct err: %w", dnsServer, err)
}
}
return nil
}

func ValidateNTPServers(dnsServers metal.NTPServers) error {
for _, ntpserver := range dnsServers {
if net.ParseIP(ntpserver.Address) != nil {
_, err := netip.ParseAddr(ntpserver.Address)
if err != nil {
return fmt.Errorf("ip: %s for ntp server not correct err: %w", ntpserver, err)
}
} else {
if !govalidator.IsDNSName(ntpserver.Address) {
return fmt.Errorf("dns name: %s for ntp server not correct", ntpserver)
}
}
}
return nil
}
25 changes: 18 additions & 7 deletions cmd/metal-api/internal/service/partition-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,31 @@ func (r *partitionResource) createPartition(request *restful.Request, response *
}

var dnsServers metal.DNSServers
reqDNSServers := requestPayload.DNSServers
if err := ValidateDNSServers(reqDNSServers); err != nil {
if len(requestPayload.DNSServers) != 0 {
for _, s := range requestPayload.DNSServers {
dnsServers = append(dnsServers, metal.DNSServer{
IP: s.IP,
})
}
}
var ntpServers metal.NTPServers
if len(requestPayload.NTPServers) != 0 {
for _, s := range requestPayload.NTPServers {
ntpServers = append(ntpServers, metal.NTPServer{
Address: s.Address,
})
}
}

if err := dnsServers.Validate(); err != nil {
r.sendError(request, response, httperrors.BadRequest(err))
return
}
dnsServers = reqDNSServers

var ntpServers metal.NTPServers
reqNtpServers := requestPayload.NTPServers
if err := ValidateNTPServers(reqNtpServers); err != nil {
if err := ntpServers.Validate(); err != nil {
r.sendError(request, response, httperrors.BadRequest(err))
return
}
ntpServers = reqNtpServers

p := &metal.Partition{
Base: metal.Base{
Expand Down
36 changes: 30 additions & 6 deletions cmd/metal-api/internal/service/v1/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type MachineAllocation struct {
VPN *MachineVPN `json:"vpn" description:"vpn connection info for machine" optional:"true"`
AllocationUUID string `json:"allocationuuid" description:"a unique identifier for this machine allocation, can be used to distinguish between machine allocations over time."`
FirewallRules *FirewallRules `json:"firewall_rules,omitempty" description:"a set of firewall rules to apply" optional:"true"`
DNSServers metal.DNSServers `json:"dns_servers,omitempty" description:"the dns servers used for the machine" optional:"true"`
NTPServers metal.NTPServers `json:"ntp_servers,omitempty" description:"the ntp servers used for the machine" optional:"true"`
DNSServers []DNSServer `json:"dns_servers,omitempty" description:"the dns servers used for the machine" optional:"true"`
NTPServers []NTPServer `json:"ntp_servers,omitempty" description:"the ntp servers used for the machine" optional:"true"`
}

type FirewallRules struct {
Expand Down Expand Up @@ -231,8 +231,8 @@ type MachineAllocateRequest struct {
Networks MachineAllocationNetworks `json:"networks" description:"the networks that this machine will be placed in." optional:"true"`
IPs []string `json:"ips" description:"the ips to attach to this machine additionally" optional:"true"`
PlacementTags []string `json:"placement_tags,omitempty" description:"by default machines are spread across the racks inside a partition for every project. if placement tags are provided, the machine candidate has an additional anti-affinity to other machines having the same tags"`
DNSServers metal.DNSServers `json:"dns_servers,omitempty" description:"the dns servers used for the machine" optional:"true"`
NTPServers metal.NTPServers `json:"ntp_servers,omitempty" description:"the ntp servers used for the machine" optional:"true"`
DNSServers []DNSServer `json:"dns_servers,omitempty" description:"the dns servers used for the machine" optional:"true"`
NTPServers []NTPServer `json:"ntp_servers,omitempty" description:"the ntp servers used for the machine" optional:"true"`
}

type MachineAllocationNetworks []MachineAllocationNetwork
Expand Down Expand Up @@ -336,6 +336,14 @@ type MachineIssue struct {
Details string `json:"details" description:"details of the issue"`
}

type DNSServer struct {
IP string `json:"ip" description:"ip address of this dns server"`
}

type NTPServer struct {
Address string `json:"address" description:"ip address or dns hostname of this ntp server"`
}

func NewMetalIPMI(r *MachineIPMI) metal.IPMI {
var chassisPartNumber string
if r.Fru.ChassisPartNumber != nil {
Expand Down Expand Up @@ -584,6 +592,22 @@ func NewMachineResponse(m *metal.Machine, s *metal.Size, p *metal.Partition, i *
}
}

var (
dnsServers []DNSServer
ntpServers []NTPServer
)

for _, s := range m.Allocation.DNSServers {
dnsServers = append(dnsServers, DNSServer{
IP: s.IP,
})
}
for _, s := range m.Allocation.NTPServers {
ntpServers = append(ntpServers, NTPServer{
Address: s.Address,
})
}

allocation = &MachineAllocation{
Creator: m.Allocation.Creator,
Created: m.Allocation.Created,
Expand All @@ -601,8 +625,8 @@ func NewMachineResponse(m *metal.Machine, s *metal.Size, p *metal.Partition, i *
VPN: NewMachineVPN(m.Allocation.VPN),
AllocationUUID: m.Allocation.UUID,
FirewallRules: firewallRules,
DNSServers: m.Allocation.DNSServers,
NTPServers: m.Allocation.NTPServers,
DNSServers: dnsServers,
NTPServers: ntpServers,
}

allocation.Reinstall = m.Allocation.Reinstall
Expand Down
24 changes: 20 additions & 4 deletions cmd/metal-api/internal/service/v1/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ type PartitionBase struct {
MgmtServiceAddress *string `json:"mgmtserviceaddress" description:"the address to the management service of this partition" optional:"true"`
PrivateNetworkPrefixLength *int `json:"privatenetworkprefixlength" description:"the length of private networks for the machine's child networks in this partition, default 22" optional:"true" minimum:"16" maximum:"30"`
Labels map[string]string `json:"labels" description:"free labels that you associate with this partition" optional:"true"`
DNSServers metal.DNSServers `json:"dns_servers" description:"the dns servers for this partition" optional:"true"`
NTPServers metal.NTPServers `json:"ntp_servers" description:"the ntp servers for this partition" optional:"true"`
DNSServers []DNSServer `json:"dns_servers" description:"the dns servers for this partition" optional:"true"`
NTPServers []NTPServer `json:"ntp_servers" description:"the ntp servers for this partition" optional:"true"`
}

type PartitionBootConfiguration struct {
Expand Down Expand Up @@ -106,6 +106,22 @@ func NewPartitionResponse(p *metal.Partition) *PartitionResponse {
labels = p.Labels
}

var (
dnsServers []DNSServer
ntpServers []NTPServer
)

for _, s := range p.DNSServers {
dnsServers = append(dnsServers, DNSServer{
IP: s.IP,
})
}
for _, s := range p.NTPServers {
ntpServers = append(ntpServers, NTPServer{
Address: s.Address,
})
}

return &PartitionResponse{
Common: Common{
Identifiable: Identifiable{
Expand All @@ -119,8 +135,8 @@ func NewPartitionResponse(p *metal.Partition) *PartitionResponse {
PartitionBase: PartitionBase{
MgmtServiceAddress: &p.MgmtServiceAddress,
PrivateNetworkPrefixLength: &prefixLength,
DNSServers: p.DNSServers,
NTPServers: p.NTPServers,
DNSServers: dnsServers,
NTPServers: ntpServers,
},
PartitionBootConfiguration: PartitionBootConfiguration{
ImageURL: &p.BootConfiguration.ImageURL,
Expand Down
Loading

0 comments on commit 5f71f78

Please sign in to comment.