// Example_rmPerms creates a series of perm configs and verifies // perm-rm works by deleting some and then all and verifying entries // have been removed via perm-ls. Also verify the default perm config // cannot be removed. func Example_rmPerms() { _, stopper := startAdminServer() defer stopper.Stop() testConfigFn := createTestConfigFile(testPermConfig) defer util.CleanupDir(testConfigFn) keys := []proto.Key{ proto.KeyMin, proto.Key("db1"), } for _, key := range keys { prefix := url.QueryEscape(string(key)) RunSetPerm(testContext, prefix, testConfigFn) } for _, key := range keys { prefix := url.QueryEscape(string(key)) RunRmPerm(testContext, prefix) RunLsPerm(testContext, "") } // Output: // set permission config for key prefix "" // set permission config for key prefix "db1" // [default] // db1 // removed permission config for key prefix "db1" // [default] }
// Example_setAndGetPerm sets perm configs for a variety of key // prefixes and verifies they can be fetched directly. func Example_setAndGetPerms() { _, stopper := startAdminServer() defer stopper.Stop() testConfigFn := createTestConfigFile(testPermConfig) defer util.CleanupDir(testConfigFn) testData := []struct { prefix proto.Key yaml string }{ {proto.KeyMin, testPermConfig}, {proto.Key("db1"), testPermConfig}, {proto.Key("db 2"), testPermConfig}, {proto.Key("\xfe"), testPermConfig}, } for _, test := range testData { prefix := url.QueryEscape(string(test.prefix)) RunSetPerm(testContext, prefix, testConfigFn) RunGetPerm(testContext, prefix) } // Output: // set permission config for key prefix "" // permission config for key prefix "": // read: // - readonly // - readwrite // write: // - readwrite // - writeonly // // set permission config for key prefix "db1" // permission config for key prefix "db1": // read: // - readonly // - readwrite // write: // - readwrite // - writeonly // // set permission config for key prefix "db+2" // permission config for key prefix "db+2": // read: // - readonly // - readwrite // write: // - readwrite // - writeonly // // set permission config for key prefix "%FE" // permission config for key prefix "%FE": // read: // - readonly // - readwrite // write: // - readwrite // - writeonly }
// Example_setAndGetZone sets zone configs for a variety of key // prefixes and verifies they can be fetched directly. func Example_setAndGetZone() { _, stopper := startAdminServer() defer stopper.Stop() testConfigFn := createTestConfigFile(testZoneConfig) defer util.CleanupDir(testConfigFn) testData := []struct { prefix proto.Key yaml string }{ {proto.KeyMin, testZoneConfig}, {proto.Key("db1"), testZoneConfig}, {proto.Key("db 2"), testZoneConfig}, {proto.Key("\xfe"), testZoneConfig}, } for _, test := range testData { prefix := url.QueryEscape(string(test.prefix)) RunSetZone(testContext, prefix, testConfigFn) RunGetZone(testContext, prefix) } // Output: // set zone config for key prefix "" // zone config for key prefix "": // replicas: // - attrs: [dc1, ssd] // - attrs: [dc2, ssd] // - attrs: [dc3, ssd] // range_min_bytes: 1048576 // range_max_bytes: 67108864 // // set zone config for key prefix "db1" // zone config for key prefix "db1": // replicas: // - attrs: [dc1, ssd] // - attrs: [dc2, ssd] // - attrs: [dc3, ssd] // range_min_bytes: 1048576 // range_max_bytes: 67108864 // // set zone config for key prefix "db+2" // zone config for key prefix "db+2": // replicas: // - attrs: [dc1, ssd] // - attrs: [dc2, ssd] // - attrs: [dc3, ssd] // range_min_bytes: 1048576 // range_max_bytes: 67108864 // // set zone config for key prefix "%FE" // zone config for key prefix "%FE": // replicas: // - attrs: [dc1, ssd] // - attrs: [dc2, ssd] // - attrs: [dc3, ssd] // range_min_bytes: 1048576 // range_max_bytes: 67108864 }
// Example_lsPerms creates a series of perm configs and verifies // perm-ls works. First, no regexp lists all perm configs. Second, // regexp properly matches results. func Example_lsPerms() { _, stopper := startAdminServer() defer stopper.Stop() testConfigFn := createTestConfigFile(testPermConfig) defer util.CleanupDir(testConfigFn) keys := []proto.Key{ proto.KeyMin, proto.Key("db1"), proto.Key("db2"), proto.Key("db3"), proto.Key("user"), } regexps := []string{ "", "db*", "db[12]", } for _, key := range keys { prefix := url.QueryEscape(string(key)) RunSetPerm(testContext, prefix, testConfigFn) } for i, regexp := range regexps { fmt.Fprintf(os.Stdout, "test case %d: %q\n", i, regexp) if regexp == "" { RunLsPerm(testContext, "") } else { RunLsPerm(testContext, regexp) } } // Output: // set permission config for key prefix "" // set permission config for key prefix "db1" // set permission config for key prefix "db2" // set permission config for key prefix "db3" // set permission config for key prefix "user" // test case 0: "" // [default] // db1 // db2 // db3 // user // test case 1: "db*" // db1 // db2 // db3 // test case 2: "db[12]" // db1 // db2 }
// This is just the mechanics of certs generation. func TestGenerateCerts(t *testing.T) { defer leaktest.AfterTest(t)() // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) // Try certs generation with empty Certs dir argument. err := security.RunCreateCACert("", "", 512) if err == nil { t.Fatalf("Expected error, but got none") } err = security.RunCreateNodeCert( "", "", "", "", 512, []string{"localhost"}) if err == nil { t.Fatalf("Expected error, but got none") } // Try generating node certs without CA certs present. err = security.RunCreateNodeCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey), 512, []string{"localhost"}) if err == nil { t.Fatalf("Expected error, but got none") } // Now try in the proper order. err = security.RunCreateCACert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey), 512, []string{"localhost"}) if err != nil { t.Fatalf("Expected success, got %v", err) } }
// Example_setAndGetAccts sets acct configs for a variety of key // prefixes and verifies they can be fetched directly. func Example_setAndGetAccts() { _, stopper := startAdminServer() defer stopper.Stop() testConfigFn := createTestConfigFile(testAcctConfig) defer util.CleanupDir(testConfigFn) testData := []struct { prefix proto.Key yaml string }{ {proto.KeyMin, testAcctConfig}, {proto.Key("db1"), testAcctConfig}, {proto.Key("db 2"), testAcctConfig}, {proto.Key("\xfe"), testAcctConfig}, } for _, test := range testData { prefix := url.QueryEscape(string(test.prefix)) RunSetAcct(testContext, prefix, testConfigFn) RunGetAcct(testContext, prefix) } // Output: // set accounting config for key prefix "" // accounting config for key prefix "": // cluster_id: test // // set accounting config for key prefix "db1" // accounting config for key prefix "db1": // cluster_id: test // // set accounting config for key prefix "db+2" // accounting config for key prefix "db+2": // cluster_id: test // // set accounting config for key prefix "%FE" // accounting config for key prefix "%FE": // cluster_id: test }
// This is a fairly high-level test of CA and node certificates. // We construct SSL server and clients and use the generated certs. func TestUseCerts(t *testing.T) { defer leaktest.AfterTest(t)() // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) err := security.RunCreateCACert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey), 512, []string{"127.0.0.1"}) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateClientCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedRootCert), filepath.Join(certsDir, security.EmbeddedRootKey), 512, security.RootUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Load TLS Configs. This is what TestServer and HTTPClient do internally. _, err = security.LoadServerTLSConfig( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey)) if err != nil { t.Fatalf("Expected success, got %v", err) } _, err = security.LoadClientTLSConfig( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey)) if err != nil { t.Fatalf("Expected success, got %v", err) } // Start a test server and override certs. // We use a real context since we want generated certs. params := base.TestServerArgs{ SSLCA: filepath.Join(certsDir, security.EmbeddedCACert), SSLCert: filepath.Join(certsDir, security.EmbeddedNodeCert), SSLCertKey: filepath.Join(certsDir, security.EmbeddedNodeKey), } s, _, _ := serverutils.StartServer(t, params) defer s.Stopper().Stop() // Insecure mode. clientContext := testutils.NewNodeTestBaseContext() clientContext.Insecure = true httpClient, err := clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } req, err := http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err := httpClient.Do(req) if err == nil { resp.Body.Close() t.Fatalf("Expected SSL error, got success") } // Secure mode but no Certs: permissive config. clientContext = testutils.NewNodeTestBaseContext() clientContext.Insecure = false clientContext.SSLCert = "" httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } // Endpoint that does not enforce client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } // New client. With certs this time. clientContext = testutils.NewNodeTestBaseContext() clientContext.SSLCA = filepath.Join(certsDir, security.EmbeddedCACert) clientContext.SSLCert = filepath.Join(certsDir, security.EmbeddedNodeCert) clientContext.SSLCertKey = filepath.Join(certsDir, security.EmbeddedNodeKey) httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatalf("Expected success, got %v", err) } req, err = http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } }
// This is a fairly high-level test of CA and node certificates. // We construct SSL server and clients and use the generated certs. func TestUseCerts(t *testing.T) { defer leaktest.AfterTest(t) // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) err := security.RunCreateCACert(certsDir, 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert(certsDir, 512, []string{"127.0.0.1"}) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateClientCert(certsDir, 512, security.RootUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Load TLS Configs. This is what TestServer and HTTPClient do internally. _, err = security.LoadServerTLSConfig(certsDir, "node") if err != nil { t.Fatalf("Expected success, got %v", err) } _, err = security.LoadClientTLSConfig(certsDir, security.NodeUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Start a test server and override certs. // We use a real context since we want generated certs. testCtx := server.NewContext() testCtx.Certs = certsDir testCtx.User = security.NodeUser testCtx.Addr = "127.0.0.1:0" testCtx.PGAddr = "127.0.0.1:0" s := &server.TestServer{Ctx: testCtx} if err := s.Start(); err != nil { t.Fatal(err) } defer s.Stop() // Insecure mode. clientContext := testutils.NewNodeTestBaseContext() clientContext.Insecure = true httpClient, err := clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } req, err := http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err := httpClient.Do(req) if err == nil { resp.Body.Close() t.Fatalf("Expected SSL error, got success") } // Secure mode but no Certs directory: permissive config. clientContext = testutils.NewNodeTestBaseContext() clientContext.Certs = "" httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } // Endpoint that does not enforce client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } // Endpoint that enforces client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+driver.Endpoint, nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusUnauthorized { t.Fatalf("Expected status code %d, got: %d", http.StatusUnauthorized, resp.StatusCode) } // New client. With certs this time. clientContext = testutils.NewNodeTestBaseContext() clientContext.Certs = certsDir httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatalf("Expected success, got %v", err) } req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } }