Skip to content

Commit

Permalink
fix(cortex): pass tenant ID and fix namespace (#149)
Browse files Browse the repository at this point in the history
* fix(cortex): pass tenant ID and fix namespace

* fix(slack): populate channel_type
  • Loading branch information
mabdh authored Nov 17, 2022
1 parent 6d5a5b2 commit f37fc78
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 103 deletions.
15 changes: 12 additions & 3 deletions core/namespace/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,25 @@ func (s *Service) Update(ctx context.Context, ns *Namespace) error {
return errors.ErrInvalid.WithCausef("namespace is nil").WithMsgf("incoming namespace is empty")
}

prov, err := s.providerService.Get(ctx, ns.Provider.ID)
encryptedNS, err := s.repository.Get(ctx, ns.ID)
if err != nil {
return err
}

pluginService, err := s.getProviderPluginService(prov.Type)
existingNS, err := s.decrypt(encryptedNS)
if err != nil {
return err
}

pluginService, err := s.getProviderPluginService(existingNS.Provider.Type)
if err != nil {
return err
}

// urn is immutable
ns.URN = existingNS.URN
ns.Provider = existingNS.Provider

encryptedNamespace, err := s.encrypt(ns)
if err != nil {
return err
Expand All @@ -150,7 +159,7 @@ func (s *Service) Update(ctx context.Context, ns *Namespace) error {
return err
}

if err := pluginService.SyncRuntimeConfig(ctx, ns.URN, *prov); err != nil {
if err := pluginService.SyncRuntimeConfig(ctx, ns.URN, ns.Provider); err != nil {
if err := s.repository.Rollback(ctx, err); err != nil {
return err
}
Expand Down
68 changes: 43 additions & 25 deletions core/namespace/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func TestService_UpdateNamespace(t *testing.T) {
type testCase struct {
Description string
NSpace *namespace.Namespace
Setup func(*mocks.NamespaceRepository, *mocks.Encryptor, *mocks.ProviderService, *mocks.ConfigSyncer, testCase)
Setup func(*mocks.NamespaceRepository, *mocks.Encryptor, *mocks.ConfigSyncer, testCase)
Err error
}
var (
Expand All @@ -483,8 +483,19 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error if provider service return error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(nil, errors.New("some error"))
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(nil, errors.New("some error"))
},
NSpace: &namespace.Namespace{
Credentials: map[string]interface{}{},
},
Err: errors.New("some error"),
},
{
Description: "should return error if decrypt return error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("", errors.New("some error"))
},
NSpace: &namespace.Namespace{
Credentials: map[string]interface{}{},
Expand All @@ -493,8 +504,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error if encrypt return error caused credential is not in json",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
},
NSpace: &namespace.Namespace{
Credentials: map[string]interface{}{
Expand All @@ -505,8 +517,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error if encrypt return error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("", errors.New("some error"))
},
NSpace: &namespace.Namespace{
Expand All @@ -518,8 +531,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error if update repository error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -537,8 +551,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error not found if update repository return not found error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -556,8 +571,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error not found if update repository return relation error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -575,8 +591,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error conflict if update repository return error duplicate",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -594,8 +611,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return error if sync config return error",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -614,8 +632,9 @@ func TestService_UpdateNamespace(t *testing.T) {
},
{
Description: "should return nil error if update repository success",
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, ps *mocks.ProviderService, cs *mocks.ConfigSyncer, tc testCase) {
ps.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&provider.Provider{Type: testProviderType}, nil)
Setup: func(rr *mocks.NamespaceRepository, e *mocks.Encryptor, cs *mocks.ConfigSyncer, tc testCase) {
rr.EXPECT().Get(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("uint64")).Return(&namespace.EncryptedNamespace{Namespace: &namespace.Namespace{Provider: provider.Provider{Type: testProviderType}}}, nil)
e.EXPECT().Decrypt(mock.AnythingOfType("secret.MaskableString")).Return("{ \"key\": \"value\" }", nil)
e.EXPECT().Encrypt(mock.AnythingOfType("secret.MaskableString")).Return("some-ciphertext", nil)
rr.EXPECT().WithTransaction(mock.AnythingOfType("*context.emptyCtx")).Return(ctx)
rr.EXPECT().Update(mock.AnythingOfType("*context.emptyCtx"), &namespace.EncryptedNamespace{
Expand All @@ -638,19 +657,18 @@ func TestService_UpdateNamespace(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.Description, func(t *testing.T) {
var (
repositoryMock = new(mocks.NamespaceRepository)
encryptorMock = new(mocks.Encryptor)
providerServiceMock = new(mocks.ProviderService)
providerPluginMock = new(mocks.ConfigSyncer)
repositoryMock = new(mocks.NamespaceRepository)
encryptorMock = new(mocks.Encryptor)
providerPluginMock = new(mocks.ConfigSyncer)
)
svc := namespace.NewService(encryptorMock, repositoryMock, providerServiceMock,
svc := namespace.NewService(encryptorMock, repositoryMock, nil,
map[string]namespace.ConfigSyncer{
testProviderType: providerPluginMock,
},
)

if tc.Setup != nil {
tc.Setup(repositoryMock, encryptorMock, providerServiceMock, providerPluginMock, tc)
tc.Setup(repositoryMock, encryptorMock, providerPluginMock, tc)
}

err := svc.Update(ctx, tc.NSpace)
Expand Down
26 changes: 0 additions & 26 deletions plugins/providers/cortex/context.go

This file was deleted.

35 changes: 0 additions & 35 deletions plugins/providers/cortex/context_test.go

This file was deleted.

15 changes: 8 additions & 7 deletions plugins/providers/cortex/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,12 @@ func (s *PluginService) SyncRuntimeConfig(ctx context.Context, namespaceURN stri
"helper.tmpl": s.helperTemplate,
}

cortexClient, err := s.getCortexClient(prov.Host)
cortexClient, err := s.getCortexClient(prov.Host, namespaceURN)
if err != nil {
return err
}

if err = cortexClient.CreateAlertmanagerConfig(newContextWithTenantID(ctx, namespaceURN), cfg, templates); err != nil {
if err = cortexClient.CreateAlertmanagerConfig(ctx, cfg, templates); err != nil {
return err
}
return nil
Expand All @@ -164,7 +164,7 @@ func (s *PluginService) UpsertRule(ctx context.Context, namespaceURN string, pro
return err
}

cortexClient, err := s.getCortexClient(prov.Host)
cortexClient, err := s.getCortexClient(prov.Host, namespaceURN)
if err != nil {
return err
}
Expand All @@ -174,7 +174,7 @@ func (s *PluginService) UpsertRule(ctx context.Context, namespaceURN string, pro
return errors.ErrInvalid.WithMsgf("cannot parse upserted rule").WithCausef(err.Error())
}

cortexRuleGroup, err := cortexClient.GetRuleGroup(newContextWithTenantID(ctx, namespaceURN), rl.Namespace, rl.GroupName)
cortexRuleGroup, err := cortexClient.GetRuleGroup(ctx, rl.Namespace, rl.GroupName)
if err != nil {
if errors.Is(err, client.ErrResourceNotFound) {
cortexRuleGroup = &rwrulefmt.RuleGroup{}
Expand All @@ -189,7 +189,7 @@ func (s *PluginService) UpsertRule(ctx context.Context, namespaceURN string, pro
}

if len(newRuleNodes) == 0 {
if err := cortexClient.DeleteRuleGroup(newContextWithTenantID(ctx, namespaceURN), rl.Namespace, rl.GroupName); err != nil {
if err := cortexClient.DeleteRuleGroup(ctx, rl.Namespace, rl.GroupName); err != nil {
if err.Error() == "requested resource not found" {
return nil
}
Expand All @@ -204,7 +204,7 @@ func (s *PluginService) UpsertRule(ctx context.Context, namespaceURN string, pro
Rules: newRuleNodes,
},
}
if err := cortexClient.CreateRuleGroup(newContextWithTenantID(ctx, namespaceURN), rl.Namespace, *cortexRuleGroup); err != nil {
if err := cortexClient.CreateRuleGroup(ctx, rl.Namespace, *cortexRuleGroup); err != nil {
return fmt.Errorf("error calling cortex: %w", err)
}
return nil
Expand Down Expand Up @@ -265,12 +265,13 @@ func (s *PluginService) generateAlertmanagerConfig(tmplConfig TemplateConfig) (s
return configStr, nil
}

func (s *PluginService) getCortexClient(address string) (CortexCaller, error) {
func (s *PluginService) getCortexClient(address string, tenant string) (CortexCaller, error) {
if s.cortexClient != nil {
return s.cortexClient, nil
}
cortexClient, err := client.New(client.Config{
Address: address,
ID: tenant,
})
if err != nil {
return nil, err
Expand Down
Loading

0 comments on commit f37fc78

Please sign in to comment.