mirror of
https://github.com/psviderski/uncloud.git
synced 2026-10-08 14:14:52 +00:00
feat(dns): implement DNS names for machines in m.internal (#359)
* feat(dns): implement extra dns names for machine in m.internal This implements <machinename>.m.internal and <machineid>.m.internal as names that can be queried in the cluster. Listing all machines/services is not implemented, this may come later. Fixes: #340 Signed-off-by: Miek Gieben <miek@miek.nl> * Implement getting all machine address A query for m.internal returns all ip address There is no overflow check Signed-off-by: Miek Gieben <miek@miek.nl> --------- Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
1 parent
5e26cfbead
commit
0cdf721a6a
4 files changed
+133
-16
No files matched your search
@@ -10,6 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/psviderski/uncloud/internal/machine/api/pb"
|
||||
"github.com/psviderski/uncloud/internal/machine/network"
|
||||
"github.com/psviderski/uncloud/internal/machine/store"
|
||||
)
|
||||
|
||||
@@ -19,7 +21,9 @@ type ClusterResolver struct {
|
||||
store *store.Store
|
||||
// serviceIPs maps service names to container IPs.
|
||||
serviceIPs map[string][]netip.Addr
|
||||
// mu protects the serviceIPs map.
|
||||
// machineIPs maps machine IDs and names to their IP.
|
||||
machineIPs map[string]netip.Addr
|
||||
// mu protects the serviceIPs and machineIPs map.
|
||||
mu sync.RWMutex
|
||||
// lastUpdate tracks when records were last updated.
|
||||
lastUpdate time.Time
|
||||
@@ -46,6 +50,13 @@ func (r *ClusterResolver) Run(ctx context.Context) error {
|
||||
// TODO: implement machine membership check using Corrossion Admin client to filter available containers.
|
||||
r.updateServiceIPs(containers)
|
||||
|
||||
machines, mchanges, err := r.store.SubscribeMachines(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("subscribe to machine changes: %w", err)
|
||||
}
|
||||
r.log.Info("Subscribed to machine changes in the clsuter to keep machine DNS records updated.")
|
||||
r.updateMachineIPs(machines)
|
||||
|
||||
for {
|
||||
select {
|
||||
case _, ok := <-changes:
|
||||
@@ -59,9 +70,22 @@ func (r *ClusterResolver) Run(ctx context.Context) error {
|
||||
r.log.Error("Failed to list containers.", "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: implement machine membership check using Corrossion Admin client to filter available containers.
|
||||
r.updateServiceIPs(containers)
|
||||
|
||||
case _, ok := <-mchanges:
|
||||
if !ok {
|
||||
return fmt.Errorf("machine subscription failed")
|
||||
}
|
||||
r.log.Debug("Cluster machines changed, updating DNS records.")
|
||||
|
||||
machines, err := r.store.ListMachines(ctx)
|
||||
if err != nil {
|
||||
r.log.Error("Failed to list machines.", "err", err)
|
||||
continue
|
||||
}
|
||||
r.updateMachineIPs(machines)
|
||||
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
}
|
||||
@@ -121,19 +145,49 @@ func (r *ClusterResolver) updateServiceIPs(containers []store.ContainerRecord) {
|
||||
r.log.Info("DNS records updated.", "services", len(newServiceIPs)/3, "containers", containersCount)
|
||||
}
|
||||
|
||||
// Resolve returns IP addresses of the service containers.
|
||||
func (r *ClusterResolver) Resolve(serviceName string) []netip.Addr {
|
||||
func (r *ClusterResolver) updateMachineIPs(machines []*pb.MachineInfo) {
|
||||
newMachineIPs := make(map[string]netip.Addr, len(machines))
|
||||
|
||||
for _, machine := range machines {
|
||||
subnet, err := machine.Network.Subnet.ToPrefix()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
addr := network.MachineIP(subnet)
|
||||
newMachineIPs[machine.Name+".m"] = addr
|
||||
newMachineIPs[machine.Id+".m"] = addr
|
||||
}
|
||||
r.mu.Lock()
|
||||
r.machineIPs = newMachineIPs
|
||||
r.mu.Unlock()
|
||||
|
||||
r.log.Info("DNS records updated.", "machines", len(machines))
|
||||
}
|
||||
|
||||
// Resolve returns IP addresses of the service containers or machines.
|
||||
func (r *ClusterResolver) Resolve(name string) []netip.Addr {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
ips, ok := r.serviceIPs[serviceName]
|
||||
if !ok || len(ips) == 0 {
|
||||
return nil
|
||||
// Return a copy of the IPs slice to prevent modification of the original.
|
||||
ips, ok := r.serviceIPs[name]
|
||||
if ok && len(ips) > 0 {
|
||||
return slices.Clone(ips)
|
||||
}
|
||||
|
||||
// Return a copy of the IPs slice to prevent modification of the original.
|
||||
ipsCopy := make([]netip.Addr, len(ips))
|
||||
copy(ipsCopy, ips)
|
||||
ip, ok := r.machineIPs[name]
|
||||
if ok {
|
||||
return slices.Clone([]netip.Addr{ip})
|
||||
}
|
||||
|
||||
return ipsCopy
|
||||
if name == "m" { // all machines subdomain
|
||||
// collect all unique IP address
|
||||
uniq := map[string]netip.Addr{}
|
||||
for _, addr := range r.machineIPs {
|
||||
uniq[addr.String()] = addr
|
||||
}
|
||||
return slices.Clone(slices.Collect(maps.Values(uniq)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user