blob: 512cb98aa005b780e7e5a7ce3b9cf6306d8799e0 [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"
Mateusz Zalegab2cac082022-07-14 14:55:43 +02008 "log"
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
Mateusz Zalegadb75e212022-08-04 17:31:34 +020020func dialAuthenticated(ctx context.Context) *grpc.ClientConn {
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) {
Mateusz Zalega18a67b02022-08-02 13:37:50 +020025 log.Fatalf("You have to take ownership of the cluster first: %v", err)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020026 }
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000027 if err != nil {
28 log.Fatalf("Failed to get owner credentials: %v", err)
29 }
Mateusz Zalegadb75e212022-08-04 17:31:34 +020030 if len(flags.clusterEndpoints) == 0 {
31 log.Fatal("Please provide at least one cluster endpoint using the --endpoint parameter.")
32 }
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010033
34 ca, err := core.GetClusterCAWithTOFU(ctx, connectOptions())
35 if err != nil {
36 log.Fatalf("Failed to get cluster CA: %v", err)
37 }
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 {
46 log.Fatalf("While configuring dial options: %v", err)
47 }
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 {
Serge Bazanski7eeef0f2024-02-05 14:40:15 +010052 log.Fatalf("While dialing cluster: %v", err)
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020053 }
Mateusz Zalega18a67b02022-08-02 13:37:50 +020054 return cc
Mateusz Zalegad5f2f7a2022-07-05 18:48:56 +020055}
Serge Bazanskib91938f2023-03-29 14:31:22 +020056
57func dialAuthenticatedNode(ctx context.Context, id, address string, cacert *x509.Certificate) *grpc.ClientConn {
58 // 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) {
Serge Bazanskib91938f2023-03-29 14:31:22 +020062 log.Fatalf("You have to take ownership of the cluster first: %v", err)
63 }
64 cc, err := core.DialNode(ctx, opkey, ocert, cacert, flags.proxyAddr, id, address)
65 if err != nil {
66 log.Fatalf("While dialing node: %v", err)
67 }
68 return cc
69}
Serge Bazanskia3e38cf2024-07-31 14:40:04 +000070
71func newAuthenticatedNodeHTTPTransport(ctx context.Context, id string) *http.Transport {
72 cacert, err := core.GetClusterCAWithTOFU(ctx, connectOptions())
73 if err != nil {
74 log.Fatalf("Could not get CA certificate: %v", err)
75 }
76 ocert, opkey, err := core.GetOwnerCredentials(flags.configPath)
77 if errors.Is(err, core.ErrNoCredentials) {
78 log.Fatalf("You have to take ownership of the cluster first: %v", err)
79 }
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 {
91 log.Fatalf("Failed to create proxy dialer: %v", err)
92 }
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 }
98 return transport
99}