Skip to content

Commit b5145b9

Browse files
committed
roachprod: add CLI option to download certs dir
This change adds a fetch-certs command that will download the pgurl certs from a cluster locally. We need a separate command for certs as opposed to just using roachprod get as lib/pq will complain about world-readable files. One benefactor of this command is testing out new roachtest operations locally. Many operations require certs and having to manually remember to make them non world readable each time is non obvious and cumbersome.
1 parent c324bab commit b5145b9

File tree

4 files changed

+59
-15
lines changed

4 files changed

+59
-15
lines changed

pkg/cmd/roachprod/cli/commands.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,3 +2207,31 @@ If the time is not provided, it downloads the latest pprof file across all clust
22072207
}),
22082208
}
22092209
}
2210+
2211+
func (cr *commandRegistry) buildFetchCertsDir() *cobra.Command {
2212+
return &cobra.Command{
2213+
Use: "fetch-certs <cluster> [<dest-dir>]",
2214+
Short: "downloads the PGUrl certs directory from the cluster",
2215+
Long: fmt.Sprintf(`
2216+
Downloads the PGUrl certs directory from the cluster. In addition to downloading the
2217+
certs, it also makes sure the files are not world readable so lib/pq doesn't complain.
2218+
If a destination is not provided, the certs will be downloaded to a default %s directory.
2219+
2220+
--certs-dir: specify the directory to download the certs from
2221+
2222+
`, install.CockroachNodeCertsDir),
2223+
Args: cobra.RangeArgs(1, 2),
2224+
Run: wrap(func(cmd *cobra.Command, args []string) error {
2225+
cluster := args[0]
2226+
// If a destination is not provided, download the certs to a default directory
2227+
// for safety. FetchCertsDir will walk the entire directory and chmod each file
2228+
// so we want to avoid side effects.
2229+
dest := fmt.Sprintf("./%s", install.CockroachNodeCertsDir)
2230+
if len(args) == 2 {
2231+
dest = args[1]
2232+
}
2233+
ctx := context.Background()
2234+
return roachprod.FetchCertsDir(ctx, config.Logger, cluster, pgurlCertsDir, dest)
2235+
}),
2236+
}
2237+
}

pkg/cmd/roachprod/cli/resgistry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,6 @@ func (cr *commandRegistry) register() {
7070
cr.buildOpentelemetryStopCmd(),
7171
cr.buildFetchLogsCmd(),
7272
cr.buildGetLatestPProfCmd(),
73+
cr.buildFetchCertsDir(),
7374
})
7475
}

pkg/cmd/roachtest/cluster.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"encoding/json"
1414
"fmt"
1515
"io"
16-
"io/fs"
1716
"log"
1817
"math/rand"
1918
"net"
@@ -2203,6 +2202,7 @@ func (c *clusterImpl) StartE(
22032202
// Do not refetch certs if that step already happened once (i.e., we
22042203
// are restarting a node).
22052204
if settings.Secure && c.localCertsDir == "" {
2205+
// Get the certs from the first node.
22062206
if err := c.RefetchCertsFromNode(ctx, 1); err != nil {
22072207
return err
22082208
}
@@ -2279,6 +2279,7 @@ func (c *clusterImpl) StartServiceForVirtualClusterE(
22792279
}
22802280

22812281
if settings.Secure {
2282+
// Get the certs from the first node.
22822283
if err := c.RefetchCertsFromNode(ctx, 1); err != nil {
22832284
return err
22842285
}
@@ -2336,20 +2337,7 @@ func (c *clusterImpl) RefetchCertsFromNode(ctx context.Context, node int) error
23362337
// certs. Bypass that distinction (which should be fixed independently, but
23372338
// that might cause fallout) by using a non-existing dir here.
23382339
c.localCertsDir = filepath.Join(c.localCertsDir, install.CockroachNodeCertsDir)
2339-
// Get the certs from the first node.
2340-
if err := c.Get(ctx, c.l, fmt.Sprintf("./%s", install.CockroachNodeCertsDir), c.localCertsDir, c.Node(node)); err != nil {
2341-
return errors.Wrap(err, "cluster.StartE")
2342-
}
2343-
// Need to prevent world readable files or lib/pq will complain.
2344-
return filepath.WalkDir(c.localCertsDir, func(path string, d fs.DirEntry, err error) error {
2345-
if err != nil {
2346-
return errors.Wrap(err, "walking localCertsDir failed")
2347-
}
2348-
if d.IsDir() {
2349-
return nil
2350-
}
2351-
return os.Chmod(path, 0600)
2352-
})
2340+
return roachprod.FetchCertsDir(ctx, c.l, c.MakeNodes(c.Node(node)), fmt.Sprintf("./%s", install.CockroachNodeCertsDir), c.localCertsDir)
23532341
}
23542342

23552343
func (c *clusterImpl) SetDefaultVirtualCluster(name string) {

pkg/roachprod/roachprod.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/json"
1212
"fmt"
1313
"io"
14+
"io/fs"
1415
"net"
1516
"net/http"
1617
"net/url"
@@ -3177,3 +3178,29 @@ func FetchLogs(
31773178
return errors.Wrap(c.Get(ctx, l, c.Nodes, "logs/redacted/combined.log" /* src */, dest), "cluster.FetchLogs")
31783179
})
31793180
}
3181+
3182+
// FetchCertsDir downloads the certs directory from the cluster using `roachprod get`
3183+
// and ensures the files are not world readable.
3184+
func FetchCertsDir(
3185+
ctx context.Context, l *logger.Logger, clusterName, certsDir, destinationDir string,
3186+
) error {
3187+
c, err := GetClusterFromCache(l, clusterName)
3188+
if err != nil {
3189+
return err
3190+
}
3191+
3192+
if err = c.Get(ctx, l, c.Nodes, certsDir, destinationDir); err != nil {
3193+
return err
3194+
}
3195+
3196+
// Need to prevent world readable files or lib/pq will complain.
3197+
return filepath.WalkDir(destinationDir, func(path string, d fs.DirEntry, err error) error {
3198+
if err != nil {
3199+
return errors.Wrap(err, "walking localCertsDir failed")
3200+
}
3201+
if d.IsDir() {
3202+
return nil
3203+
}
3204+
return os.Chmod(path, 0600)
3205+
})
3206+
}

0 commit comments

Comments
 (0)