blob: cfe1b411ccc71135624e3b88d75e613be54674c9 [file] [log] [blame]
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +02001package main
2
3import (
4 "context"
Serge Bazanski925ec3d2024-02-05 14:38:20 +01005 "crypto/tls"
Serge Bazanskib91938f2023-03-29 14:31:22 +02006 "crypto/x509"
Tim Windelschmidtd5f851b2024-04-23 14:59:37 +02007 "errors"
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +02008 "fmt"
Serge Bazanskia3e38cf2024-07-31 14:40:04 +00009 "net"
10 "net/http"
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020011
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000012 "golang.org/x/net/proxy"
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020013 "google.golang.org/grpc"
14
Mateusz Zalega18a67b02022-08-02 13:37:50 +020015 "source.monogon.dev/metropolis/cli/metroctl/core"
Serge Bazanski925ec3d2024-02-05 14:38:20 +010016 "source.monogon.dev/metropolis/node/core/rpc"
17 "source.monogon.dev/metropolis/node/core/rpc/resolver"
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020018)
19
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020020func dialAuthenticated(ctx context.Context) (*grpc.ClientConn, error) {
Mateusz Zalega18a67b02022-08-02 13:37:50 +020021 // Collect credentials, validate command parameters, and try dialing the
22 // cluster.
Serge Bazanskicf23ebc2023-03-14 17:02:04 +010023 ocert, opkey, err := core.GetOwnerCredentials(flags.configPath)
Tim Windelschmidt513df182024-04-18 23:44:50 +020024 if errors.Is(err, core.ErrNoCredentials) {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020025 return nil, fmt.Errorf("you have to take ownership of the cluster first: %w", err)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020026 }
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000027 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020028 return nil, fmt.Errorf("failed to get owner credentials: %w", err)
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000029 }
Mateusz Zalegadb75e212022-08-04 17:31:34 +020030 if len(flags.clusterEndpoints) == 0 {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020031 return nil, fmt.Errorf("please provide at least one cluster endpoint using the --endpoint parameter")
Mateusz Zalegadb75e212022-08-04 17:31:34 +020032 }
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010033
34 ca, err := core.GetClusterCAWithTOFU(ctx, connectOptions())
35 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020036 return nil, fmt.Errorf("failed to get cluster CA: %w", err)
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010037 }
38
Serge Bazanski925ec3d2024-02-05 14:38:20 +010039 tlsc := tls.Certificate{
40 Certificate: [][]byte{ocert.Raw},
41 PrivateKey: opkey,
42 }
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010043 creds := rpc.NewAuthenticatedCredentials(tlsc, rpc.WantRemoteCluster(ca))
Serge Bazanski925ec3d2024-02-05 14:38:20 +010044 opts, err := core.DialOpts(ctx, connectOptions())
45 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020046 return nil, fmt.Errorf("while configuring dial options: %w", err)
Serge Bazanski925ec3d2024-02-05 14:38:20 +010047 }
48 opts = append(opts, grpc.WithTransportCredentials(creds))
49
50 cc, err := grpc.Dial(resolver.MetropolisControlAddress, opts...)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020051 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020052 return nil, fmt.Errorf("while dialing cluster: %w", err)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020053 }
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020054 return cc, nil
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020055}
Serge Bazanskib91938f2023-03-29 14:31:22 +020056
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020057func dialAuthenticatedNode(ctx context.Context, id, address string, cacert *x509.Certificate) (*grpc.ClientConn, error) {
Serge Bazanskib91938f2023-03-29 14:31:22 +020058 // Collect credentials, validate command parameters, and try dialing the
59 // cluster.
60 ocert, opkey, err := core.GetOwnerCredentials(flags.configPath)
Tim Windelschmidt513df182024-04-18 23:44:50 +020061 if errors.Is(err, core.ErrNoCredentials) {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020062 return nil, fmt.Errorf("you have to take ownership of the cluster first: %w", err)
Serge Bazanskib91938f2023-03-29 14:31:22 +020063 }
64 cc, err := core.DialNode(ctx, opkey, ocert, cacert, flags.proxyAddr, id, address)
65 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020066 return nil, fmt.Errorf("while dialing node: %w", err)
Serge Bazanskib91938f2023-03-29 14:31:22 +020067 }
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020068 return cc, nil
Serge Bazanskib91938f2023-03-29 14:31:22 +020069}
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000070
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020071func newAuthenticatedNodeHTTPTransport(ctx context.Context, id string) (*http.Transport, error) {
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000072 cacert, err := core.GetClusterCAWithTOFU(ctx, connectOptions())
73 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020074 return nil, fmt.Errorf("could not get CA certificate: %w", err)
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000075 }
76 ocert, opkey, err := core.GetOwnerCredentials(flags.configPath)
77 if errors.Is(err, core.ErrNoCredentials) {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020078 return nil, fmt.Errorf("you have to take ownership of the cluster first: %w", err)
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000079 }
80 tlsc := tls.Certificate{
81 Certificate: [][]byte{ocert.Raw},
82 PrivateKey: opkey,
83 }
84 tlsconf := rpc.NewAuthenticatedTLSConfig(tlsc, rpc.WantRemoteCluster(cacert), rpc.WantRemoteNode(id))
85 transport := &http.Transport{
86 TLSClientConfig: tlsconf,
87 }
88 if flags.proxyAddr != "" {
89 dialer, err := proxy.SOCKS5("tcp", flags.proxyAddr, nil, proxy.Direct)
90 if err != nil {
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020091 return nil, fmt.Errorf("failed to create proxy dialer: %w", err)
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000092 }
93 transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
94 // TODO(q3k): handle context
95 return dialer.Dial(network, addr)
96 }
97 }
Tim Windelschmidt0b4fb8c2024-09-18 17:34:23 +020098 return transport, nil
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000099}