diff --git a/builtin/logical/rabbitmq/backend_test.go b/builtin/logical/rabbitmq/backend_test.go index a15ce32bf1..7a08f6e3e2 100644 --- a/builtin/logical/rabbitmq/backend_test.go +++ b/builtin/logical/rabbitmq/backend_test.go @@ -14,9 +14,11 @@ import ( logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" "github.com/hashicorp/vault/sdk/helper/docker" "github.com/hashicorp/vault/sdk/helper/jsonutil" + "github.com/hashicorp/vault/sdk/helper/testhelpers/observations" "github.com/hashicorp/vault/sdk/logical" rabbithole "github.com/michaelklishin/rabbit-hole/v2" "github.com/mitchellh/mapstructure" + "github.com/stretchr/testify/require" ) const ( @@ -69,7 +71,10 @@ func prepareRabbitMQTestContainer(t *testing.T) (func(), string) { } func TestBackend_basic(t *testing.T) { - b, _ := Factory(context.Background(), logical.TestBackendConfig()) + backendConfig := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + backendConfig.ObservationRecorder = or + b, _ := Factory(context.Background(), backendConfig) cleanup, uri := prepareRabbitMQTestContainer(t) defer cleanup() @@ -80,7 +85,7 @@ func TestBackend_basic(t *testing.T) { Steps: []logicaltest.TestStep{ testAccStepConfig(t, uri, ""), testAccStepRole(t), - testAccStepReadCreds(t, b, uri, roleName), + testAccStepReadCreds(t, b, or, uri, roleName), }, }) } @@ -140,6 +145,8 @@ func TestBackend_roleWithPasswordPolicy(t *testing.T) { } backendConfig := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + backendConfig.ObservationRecorder = or passGen := func() (password string, err error) { return base62.Random(30) } @@ -155,7 +162,7 @@ func TestBackend_roleWithPasswordPolicy(t *testing.T) { Steps: []logicaltest.TestStep{ testAccStepConfig(t, uri, "testpolicy"), testAccStepRole(t), - testAccStepReadCreds(t, b, uri, roleName), + testAccStepReadCreds(t, b, or, uri, roleName), }, }) } @@ -209,7 +216,7 @@ func testAccStepDeleteRole(t *testing.T, n string) logicaltest.TestStep { } } -func testAccStepReadCreds(t *testing.T, b logical.Backend, uri, name string) logicaltest.TestStep { +func testAccStepReadCreds(t *testing.T, b logical.Backend, or *observations.TestObservationRecorder, uri, name string) logicaltest.TestStep { return logicaltest.TestStep{ Operation: logical.ReadOperation, Path: "creds/" + name, @@ -245,6 +252,17 @@ func testAccStepReadCreds(t *testing.T, b logical.Backend, uri, name string) log if err != nil { return err } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) + if resp != nil { if resp.IsError() { return fmt.Errorf("error on resp: %#v", *resp) diff --git a/builtin/logical/rabbitmq/observation_consts.go b/builtin/logical/rabbitmq/observation_consts.go new file mode 100644 index 0000000000..cd4eb0fc21 --- /dev/null +++ b/builtin/logical/rabbitmq/observation_consts.go @@ -0,0 +1,17 @@ +// Copyright IBM Corp. 2016, 2025 +// SPDX-License-Identifier: BUSL-1.1 + +package rabbitmq + +const ( + ObservationTypeRabbitMQConnectionConfigWrite = "rabbitmq/connection/config/write" + ObservationTypeRabbitMQLeaseConfigWrite = "rabbitmq/lease/config/write" + ObservationTypeRabbitMQLeaseConfigRead = "rabbitmq/lease/config/read" + ObservationTypeRabbitMQRoleWrite = "rabbitmq/role/write" + ObservationTypeRabbitMQRoleRead = "rabbitmq/role/read" + ObservationTypeRabbitMQRoleDelete = "rabbitmq/role/delete" + ObservationTypeRabbitMQCredentialCreateSuccess = "rabbitmq/credential/create/success" + ObservationTypeRabbitMQCredentialCreateFail = "rabbitmq/credential/create/fail" + ObservationTypeRabbitMQCredentialRenew = "rabbitmq/credential/renew" + ObservationTypeRabbitMQCredentialRevoke = "rabbitmq/credential/revoke" +) diff --git a/builtin/logical/rabbitmq/path_config_connection.go b/builtin/logical/rabbitmq/path_config_connection.go index 92e4812898..92a2893a43 100644 --- a/builtin/logical/rabbitmq/path_config_connection.go +++ b/builtin/logical/rabbitmq/path_config_connection.go @@ -123,6 +123,8 @@ func (b *backend) pathConnectionUpdate(ctx context.Context, req *logical.Request return nil, err } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQConnectionConfigWrite, nil) + // Reset the client connection b.resetClient(ctx) diff --git a/builtin/logical/rabbitmq/path_config_connection_test.go b/builtin/logical/rabbitmq/path_config_connection_test.go index 424a446d02..8cd0e9beb6 100644 --- a/builtin/logical/rabbitmq/path_config_connection_test.go +++ b/builtin/logical/rabbitmq/path_config_connection_test.go @@ -8,13 +8,17 @@ import ( "reflect" "testing" + "github.com/hashicorp/vault/sdk/helper/testhelpers/observations" "github.com/hashicorp/vault/sdk/logical" + "github.com/stretchr/testify/require" ) func TestBackend_ConfigConnection_DefaultUsernameTemplate(t *testing.T) { var resp *logical.Response var err error config := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + config.ObservationRecorder = or config.StorageView = &logical.InmemStorage{} b := Backend() if err = b.Setup(context.Background(), config); err != nil { @@ -40,6 +44,16 @@ func TestBackend_ConfigConnection_DefaultUsernameTemplate(t *testing.T) { if resp != nil { t.Fatal("expected a nil response") } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) actualConfig, err := readConfig(context.Background(), config.StorageView) if err != nil { @@ -62,6 +76,8 @@ func TestBackend_ConfigConnection_CustomUsernameTemplate(t *testing.T) { var resp *logical.Response var err error config := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + config.ObservationRecorder = or config.StorageView = &logical.InmemStorage{} b := Backend() if err = b.Setup(context.Background(), config); err != nil { @@ -85,6 +101,16 @@ func TestBackend_ConfigConnection_CustomUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp != nil { t.Fatal("expected a nil response") } diff --git a/builtin/logical/rabbitmq/path_config_lease.go b/builtin/logical/rabbitmq/path_config_lease.go index 7f08020ae4..787aef9f89 100644 --- a/builtin/logical/rabbitmq/path_config_lease.go +++ b/builtin/logical/rabbitmq/path_config_lease.go @@ -57,10 +57,11 @@ func pathConfigLease(b *backend) *framework.Path { // Sets the lease configuration parameters func (b *backend) pathLeaseUpdate(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { - entry, err := logical.StorageEntryJSON("config/lease", &configLease{ + cl := configLease{ TTL: time.Second * time.Duration(d.Get("ttl").(int)), MaxTTL: time.Second * time.Duration(d.Get("max_ttl").(int)), - }) + } + entry, err := logical.StorageEntryJSON("config/lease", &cl) if err != nil { return nil, err } @@ -68,6 +69,11 @@ func (b *backend) pathLeaseUpdate(ctx context.Context, req *logical.Request, d * return nil, err } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQLeaseConfigWrite, map[string]interface{}{ + "ttl": cl.TTL.String(), + "max_ttl": cl.MaxTTL.String(), + }) + return nil, nil } @@ -84,6 +90,11 @@ func (b *backend) pathLeaseRead(ctx context.Context, req *logical.Request, data lease.TTL = lease.TTL / time.Second lease.MaxTTL = lease.MaxTTL / time.Second + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQLeaseConfigRead, map[string]interface{}{ + "ttl": lease.TTL.String(), + "max_ttl": lease.MaxTTL.String(), + }) + return &logical.Response{ Data: structs.New(lease).Map(), }, nil diff --git a/builtin/logical/rabbitmq/path_config_lease_test.go b/builtin/logical/rabbitmq/path_config_lease_test.go index d8f3d12c2f..eeff860597 100644 --- a/builtin/logical/rabbitmq/path_config_lease_test.go +++ b/builtin/logical/rabbitmq/path_config_lease_test.go @@ -8,13 +8,17 @@ import ( "testing" "time" + "github.com/hashicorp/vault/sdk/helper/testhelpers/observations" "github.com/hashicorp/vault/sdk/logical" + "github.com/stretchr/testify/require" ) func TestBackend_config_lease_RU(t *testing.T) { var resp *logical.Response var err error config := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + config.ObservationRecorder = or config.StorageView = &logical.InmemStorage{} b := Backend() if err = b.Setup(context.Background(), config); err != nil { @@ -38,6 +42,16 @@ func TestBackend_config_lease_RU(t *testing.T) { if resp != nil { t.Fatal("expected a nil response") } + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) configReq.Operation = logical.ReadOperation resp, err = b.HandleRequest(context.Background(), configReq) @@ -47,6 +61,16 @@ func TestBackend_config_lease_RU(t *testing.T) { if resp == nil { t.Fatal("expected a response") } + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp.Data["ttl"].(time.Duration) != 36000 { t.Fatalf("bad: ttl: expected:36000 actual:%d", resp.Data["ttl"].(time.Duration)) diff --git a/builtin/logical/rabbitmq/path_role_create.go b/builtin/logical/rabbitmq/path_role_create.go index 0b0ce6f06a..67a1466ab2 100644 --- a/builtin/logical/rabbitmq/path_role_create.go +++ b/builtin/logical/rabbitmq/path_role_create.go @@ -122,6 +122,9 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr if success { return } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQCredentialCreateFail, map[string]interface{}{ + "role_name": name, + }) // Delete the user because it's in an unknown state. resp, err := client.DeleteUser(username) if err != nil { @@ -209,6 +212,15 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr if lease != nil { response.Secret.TTL = lease.TTL response.Secret.MaxTTL = lease.MaxTTL + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQCredentialCreateSuccess, map[string]interface{}{ + "role_name": name, + "ttl": lease.TTL.String(), + "max_ttl": lease.MaxTTL.String(), + }) + } else { + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQCredentialCreateSuccess, map[string]interface{}{ + "role_name": name, + }) } return response, nil diff --git a/builtin/logical/rabbitmq/path_role_create_test.go b/builtin/logical/rabbitmq/path_role_create_test.go index 228b08b682..46d85e1be3 100644 --- a/builtin/logical/rabbitmq/path_role_create_test.go +++ b/builtin/logical/rabbitmq/path_role_create_test.go @@ -7,6 +7,7 @@ import ( "context" "testing" + "github.com/hashicorp/vault/sdk/helper/testhelpers/observations" "github.com/hashicorp/vault/sdk/logical" "github.com/stretchr/testify/require" ) @@ -18,6 +19,8 @@ func TestBackend_RoleCreate_DefaultUsernameTemplate(t *testing.T) { var resp *logical.Response var err error config := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + config.ObservationRecorder = or config.StorageView = &logical.InmemStorage{} b := Backend() if err = b.Setup(context.Background(), config); err != nil { @@ -40,6 +43,16 @@ func TestBackend_RoleCreate_DefaultUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp != nil { t.Fatal("expected a nil response") } @@ -58,6 +71,16 @@ func TestBackend_RoleCreate_DefaultUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp != nil { t.Fatal("expected a nil response") } @@ -72,6 +95,16 @@ func TestBackend_RoleCreate_DefaultUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp == nil { t.Fatal("missing creds response") } @@ -94,6 +127,8 @@ func TestBackend_RoleCreate_CustomUsernameTemplate(t *testing.T) { var resp *logical.Response var err error config := logical.TestBackendConfig() + or := observations.NewTestObservationRecorder() + config.ObservationRecorder = or config.StorageView = &logical.InmemStorage{} b := Backend() if err = b.Setup(context.Background(), config); err != nil { @@ -116,6 +151,16 @@ func TestBackend_RoleCreate_CustomUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp != nil { t.Fatal("expected a nil response") } @@ -134,6 +179,16 @@ func TestBackend_RoleCreate_CustomUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp != nil { t.Fatal("expected a nil response") } @@ -148,6 +203,16 @@ func TestBackend_RoleCreate_CustomUsernameTemplate(t *testing.T) { if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr:%s", resp, err) } + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQConnectionConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateFail)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQCredentialCreateSuccess)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRenew)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQCredentialRevoke)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigRead)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQLeaseConfigWrite)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleDelete)) + require.Equal(t, 0, or.NumObservationsByType(ObservationTypeRabbitMQRoleRead)) + require.Equal(t, 1, or.NumObservationsByType(ObservationTypeRabbitMQRoleWrite)) if resp == nil { t.Fatal("missing creds response") } diff --git a/builtin/logical/rabbitmq/path_roles.go b/builtin/logical/rabbitmq/path_roles.go index 5a06f2e5f3..1e2cb3338f 100644 --- a/builtin/logical/rabbitmq/path_roles.go +++ b/builtin/logical/rabbitmq/path_roles.go @@ -88,7 +88,16 @@ func (b *backend) pathRoleDelete(ctx context.Context, req *logical.Request, d *f return logical.ErrorResponse("missing name"), nil } - return nil, req.Storage.Delete(ctx, "role/"+name) + err := req.Storage.Delete(ctx, "role/"+name) + if err != nil { + return nil, err + } + + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQRoleDelete, map[string]interface{}{ + "role_name": name, + }) + + return nil, nil } // Reads an existing role @@ -106,6 +115,10 @@ func (b *backend) pathRoleRead(ctx context.Context, req *logical.Request, d *fra return nil, nil } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQRoleRead, map[string]interface{}{ + "role_name": name, + }) + return &logical.Response{ Data: structs.New(role).Map(), }, nil @@ -164,6 +177,10 @@ func (b *backend) pathRoleUpdate(ctx context.Context, req *logical.Request, d *f return nil, err } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQRoleWrite, map[string]interface{}{ + "role_name": name, + }) + return nil, nil } diff --git a/builtin/logical/rabbitmq/secret_creds.go b/builtin/logical/rabbitmq/secret_creds.go index f52cdd1d96..ce0ab96efd 100644 --- a/builtin/logical/rabbitmq/secret_creds.go +++ b/builtin/logical/rabbitmq/secret_creds.go @@ -46,6 +46,12 @@ func (b *backend) secretCredsRenew(ctx context.Context, req *logical.Request, d resp := &logical.Response{Secret: req.Secret} resp.Secret.TTL = lease.TTL resp.Secret.MaxTTL = lease.MaxTTL + + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQCredentialRenew, map[string]interface{}{ + "ttl": lease.TTL.String(), + "max_ttl": lease.MaxTTL.String(), + }) + return resp, nil } @@ -68,5 +74,7 @@ func (b *backend) secretCredsRevoke(ctx context.Context, req *logical.Request, d return nil, fmt.Errorf("could not delete user: %w", err) } + b.TryRecordObservationWithRequest(ctx, req, ObservationTypeRabbitMQCredentialRevoke, nil) + return nil, nil }