influxdb/notification/endpoint/service/service_test.go

185 lines
6.0 KiB
Go

package service_test
import (
"context"
"testing"
"time"
influxdb "github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/inmem"
"github.com/influxdata/influxdb/v2/kv"
"github.com/influxdata/influxdb/v2/kv/migration/all"
"github.com/influxdata/influxdb/v2/mock"
"github.com/influxdata/influxdb/v2/notification/endpoint"
"github.com/influxdata/influxdb/v2/notification/endpoint/service"
"github.com/influxdata/influxdb/v2/pkg/pointer"
"github.com/influxdata/influxdb/v2/secret"
"github.com/influxdata/influxdb/v2/tenant"
influxTesting "github.com/influxdata/influxdb/v2/testing"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"
)
var (
id1 = influxTesting.MustIDBase16Ptr("020f755c3c082000")
id2 = influxTesting.MustIDBase16Ptr("020f755c3c082001")
orgID = influxTesting.MustIDBase16Ptr("a10f755c3c082001")
userID = influxTesting.MustIDBase16Ptr("b10f755c3c082001")
timeGen1 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 13, 4, 19, 10, 0, time.UTC)}
timeGen2 = mock.TimeGenerator{FakeValue: time.Date(2006, time.July, 14, 5, 23, 53, 10, time.UTC)}
testCrudLog = influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
}
)
func newSecretService(t *testing.T, ctx context.Context, logger *zap.Logger, s kv.Store) influxdb.SecretService {
t.Helper()
tenantSvc := tenant.NewService(tenant.NewStore(s))
// initialize organization
org := influxdb.Organization{
ID: *orgID,
Name: "Test Organization",
CRUDLog: testCrudLog,
}
if err := tenantSvc.CreateOrganization(ctx, &org); err != nil {
t.Fatal(err)
}
orgID = &org.ID // orgID is generated
secretStore, err := secret.NewStore(s)
require.NoError(t, err)
return secret.NewService(secretStore)
}
// TestEndpointService_cumulativeSecrets tests that secrets are cumulatively added/updated and removed upon delete
// see https://github.com/influxdata/influxdb/pull/19082 for details
func TestEndpointService_cumulativeSecrets(t *testing.T) {
ctx := context.Background()
store := inmem.NewKVStore()
logger := zaptest.NewLogger(t)
if err := all.Up(ctx, logger, store); err != nil {
t.Fatal(err)
}
secretService := newSecretService(t, ctx, logger, store)
endpointService := service.New(service.NewStore(store), secretService)
var endpoint1 = endpoint.HTTP{
Base: endpoint.Base{
ID: id1,
Name: "name1",
OrgID: orgID,
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Headers: map[string]string{},
AuthMethod: "basic",
Method: "POST",
URL: "http://example.com",
Username: influxdb.SecretField{Key: id1.String() + "username-key", Value: pointer.String("val1")},
Password: influxdb.SecretField{Key: id1.String() + "password-key", Value: pointer.String("val2")},
}
var endpoint2 = endpoint.HTTP{
Base: endpoint.Base{
ID: id2,
Name: "name2",
OrgID: orgID,
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Headers: map[string]string{},
AuthMethod: "basic",
Method: "POST",
URL: "http://example2.com",
Username: influxdb.SecretField{Key: id2.String() + "username-key", Value: pointer.String("val3")},
Password: influxdb.SecretField{Key: id2.String() + "password-key", Value: pointer.String("val4")},
}
var err error
var secretKeys []string
// create 1st endpoint and validate secrets
if err = endpointService.CreateNotificationEndpoint(ctx, &endpoint1, *userID); err != nil {
t.Fatal(err)
}
if secretKeys, err = secretService.GetSecretKeys(ctx, *orgID); err != nil {
t.Fatal(err)
}
if len(secretKeys) != 2 {
t.Errorf("secrets after creating 1st endpoint = %v, want %v", len(secretKeys), 2)
}
// create 2nd endpoint and validate secrets
if err = endpointService.CreateNotificationEndpoint(ctx, &endpoint2, *userID); err != nil {
t.Fatal(err)
}
if secretKeys, err = secretService.GetSecretKeys(ctx, *orgID); err != nil {
t.Fatal(err)
}
if len(secretKeys) != 4 {
t.Errorf("secrets after creating 2nd endpoint = %v, want %v", len(secretKeys), 4)
}
// update 1st endpoint and validate secrets
const updatedSecretValue = "updatedSecVal"
endpoint1.Username.Value = pointer.String(updatedSecretValue)
if _, err = endpointService.UpdateNotificationEndpoint(ctx, *endpoint1.ID, &endpoint1, *userID); err != nil {
t.Fatal(err)
}
if secretKeys, err = secretService.GetSecretKeys(ctx, *orgID); err != nil {
t.Fatal(err)
}
if len(secretKeys) != 4 {
t.Errorf("secrets after updating 1st endpoint = %v, want %v", len(secretKeys), 4)
}
var secretValue string
if secretValue, err = secretService.LoadSecret(ctx, *orgID, endpoint1.Username.Key); err != nil {
t.Fatal(err)
}
if secretValue != updatedSecretValue {
t.Errorf("secret after updating 1st endpoint is not updated = %v, want %v", secretValue, updatedSecretValue)
}
// delete 1st endpoints and secrets, validate secrets
var secretsToDelete []influxdb.SecretField
if secretsToDelete, _, err = endpointService.DeleteNotificationEndpoint(ctx, *endpoint1.ID); err != nil {
t.Fatal(err)
}
if len(secretsToDelete) != 2 {
t.Errorf("2 secrets expected as a result of deleting the 1st endpoint")
}
secretService.DeleteSecret(ctx, *orgID, secretsToDelete[0].Key, secretsToDelete[1].Key)
if secretKeys, err = secretService.GetSecretKeys(ctx, *orgID); err != nil {
t.Fatal(err)
}
if len(secretKeys) != 2 {
t.Errorf("secrets after deleting 1st endpoint = %v, want %v", len(secretKeys), 2)
}
if secretsToDelete, _, err = endpointService.DeleteNotificationEndpoint(ctx, *endpoint2.ID); err != nil {
t.Fatal(err)
}
if len(secretsToDelete) != 2 {
t.Errorf("2 secrets expected as a result of deleting the 2nd endpoint")
}
secretService.DeleteSecret(ctx, *orgID, secretsToDelete[0].Key, secretsToDelete[1].Key)
if secretKeys, err = secretService.GetSecretKeys(ctx, *orgID); err != nil {
t.Fatal(err)
}
if len(secretKeys) != 0 {
t.Errorf("secrets after deleting the 2nd endpoint = %v, want %v", len(secretKeys), 2)
}
}