chore: siderolink maintenance mode
If SideroLink is enabled, maintenance mode should only allow Siderolink connections. Closes #5627 Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
parent
4551cbd7fc
commit
8c675c6692
@ -12,8 +12,10 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/state"
|
||||
ttls "github.com/talos-systems/crypto/tls"
|
||||
"github.com/talos-systems/crypto/x509"
|
||||
"github.com/talos-systems/go-procfs/procfs"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"inet.af/netaddr"
|
||||
@ -37,7 +39,12 @@ func Run(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, er
|
||||
return nil, fmt.Errorf("error waiting for the network to be ready: %w", err)
|
||||
}
|
||||
|
||||
currentAddresses, err := r.State().V1Alpha2().Resources().Get(ctx, resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.NodeAddressCurrentID, resource.VersionUndefined))
|
||||
var sideroLinkAddress netaddr.IP
|
||||
|
||||
currentAddresses, err := r.State().V1Alpha2().Resources().WatchFor(ctx,
|
||||
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.NodeAddressCurrentID, resource.VersionUndefined),
|
||||
sideroLinkAddressFinder(&sideroLinkAddress, logger),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting node addresses: %w", err)
|
||||
}
|
||||
@ -89,7 +96,7 @@ func Run(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, er
|
||||
factory.WithStreamInterceptor(injector.StreamInterceptor()),
|
||||
)
|
||||
|
||||
listener, err := factory.NewListener(factory.Port(constants.ApidPort))
|
||||
listener, err := factory.NewListener(factory.Address(formatIP(sideroLinkAddress)), factory.Port(constants.ApidPort))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -101,6 +108,10 @@ func Run(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, er
|
||||
server.Serve(listener)
|
||||
}()
|
||||
|
||||
if !sideroLinkAddress.IsZero() {
|
||||
ips = []netaddr.IP{sideroLinkAddress}
|
||||
}
|
||||
|
||||
logger.Println("this machine is reachable at:")
|
||||
|
||||
for _, ip := range ips {
|
||||
@ -134,6 +145,14 @@ func Run(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, er
|
||||
}
|
||||
}
|
||||
|
||||
func formatIP(addr netaddr.IP) string {
|
||||
if addr.IsZero() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return addr.String()
|
||||
}
|
||||
|
||||
func genTLSConfig(ips []netaddr.IP, dnsNames []string) (tlsConfig *tls.Config, provider ttls.CertificateProvider, err error) {
|
||||
ca, err := x509.NewSelfSignedCertificateAuthority()
|
||||
if err != nil {
|
||||
@ -176,3 +195,33 @@ func genTLSConfig(ips []netaddr.IP, dnsNames []string) (tlsConfig *tls.Config, p
|
||||
|
||||
return tlsConfig, provider, nil
|
||||
}
|
||||
|
||||
func sideroLinkAddressFinder(address *netaddr.IP, logger *log.Logger) state.WatchForConditionFunc {
|
||||
sideroLinkEnabled := false
|
||||
if procfs.ProcCmdline().Get(constants.KernelParamSideroLink).First() != nil {
|
||||
sideroLinkEnabled = true
|
||||
|
||||
logger.Println(constants.KernelParamSideroLink + " is enabled, waiting for address")
|
||||
}
|
||||
|
||||
return state.WithCondition(func(r resource.Resource) (bool, error) {
|
||||
if resource.IsTombstone(r) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if !sideroLinkEnabled {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
ips := r.(*network.NodeAddress).TypedSpec().IPs()
|
||||
for _, ip := range ips {
|
||||
if network.IsULA(ip, network.ULASideroLink) {
|
||||
*address = ip
|
||||
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type Registrator interface {
|
||||
|
||||
// Options is the functional options struct.
|
||||
type Options struct {
|
||||
Address string
|
||||
Port int
|
||||
SocketPath string
|
||||
Network string
|
||||
@ -50,6 +51,13 @@ type Options struct {
|
||||
// Option is the functional option func.
|
||||
type Option func(*Options)
|
||||
|
||||
// Address sets the listen address of the server.
|
||||
func Address(a string) Option {
|
||||
return func(args *Options) {
|
||||
args.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
// Port sets the listen port of the server.
|
||||
func Port(o int) Option {
|
||||
return func(args *Options) {
|
||||
@ -226,7 +234,7 @@ func NewListener(setters ...Option) (net.Listener, error) {
|
||||
return nil, fmt.Errorf("error creating containing directory for the file socket; %w", err)
|
||||
}
|
||||
case "tcp":
|
||||
address = ":" + strconv.Itoa(opts.Port)
|
||||
address = net.JoinHostPort(opts.Address, strconv.Itoa(opts.Port))
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown network: %s", opts.Network)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user