-
Notifications
You must be signed in to change notification settings - Fork 84
/
tenant_builder.go
162 lines (141 loc) · 6.45 KB
/
tenant_builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package datainputbuilder
import (
"context"
"github.com/kyma-incubator/compass/components/director/internal/model"
"github.com/kyma-incubator/compass/components/director/pkg/resource"
"github.com/kyma-incubator/compass/components/director/pkg/webhook"
"github.com/pkg/errors"
)
//go:generate mockery --exported --name=tenantRepository --output=automock --outpkg=automock --case=underscore --disable-version-string
type tenantRepository interface {
GetLowestOwnerForResource(ctx context.Context, resourceType resource.Type, objectID string) (string, error)
GetByExternalTenant(ctx context.Context, externalTenant string) (*model.BusinessTenantMapping, error)
Get(ctx context.Context, id string) (*model.BusinessTenantMapping, error)
}
// WebhookTenantBuilder takes care to get and build tenants and their labels for objects
type WebhookTenantBuilder struct {
labelInputBuilder labelInputBuilder
tenantRepository tenantRepository
}
// NewWebhookTenantBuilder creates a WebhookTenantBuilder
func NewWebhookTenantBuilder(labelInputBuilder labelInputBuilder, tenantRepository tenantRepository) *WebhookTenantBuilder {
return &WebhookTenantBuilder{
labelInputBuilder: labelInputBuilder,
tenantRepository: tenantRepository,
}
}
// GetTenantsForApplicationTemplates builds tenants with labels for application templates
func (b *WebhookTenantBuilder) GetTenantsForApplicationTemplates(ctx context.Context, tenant string, labels map[string]map[string]string, objectIDs []string) (map[string]*webhook.TenantWithLabels, error) {
tenantsForObjects := make(map[string]*webhook.TenantWithLabels)
tenantIDs := make([]string, 0)
tenantIDsMap := make(map[string]*model.BusinessTenantMapping)
objectTenantMapping := make(map[string]string)
for _, objectID := range objectIDs {
if subaccountID, ok := labels[objectID][globalSubaccountIDLabelKey]; ok {
if tenantModel, ok := tenantIDsMap[subaccountID]; ok {
tenantsForObjects[objectID] = &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: nil,
}
objectTenantMapping[objectID] = tenantModel.ID
continue
}
tenantModel, err := b.tenantRepository.GetByExternalTenant(ctx, subaccountID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant by external ID %q", subaccountID)
}
tenantsForObjects[objectID] = &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: nil,
}
tenantIDs = append(tenantIDs, tenantModel.ID)
tenantIDsMap[tenantModel.ID] = tenantModel
objectTenantMapping[objectID] = tenantModel.ID
}
}
tenantLabels, err := b.labelInputBuilder.GetLabelsForObjects(ctx, tenant, tenantIDs, model.TenantLabelableObject)
if err != nil {
return nil, errors.Wrap(err, "while listing tenant labels")
}
for objectID, tenantID := range objectTenantMapping {
tenantsForObjects[objectID].Labels = tenantLabels[tenantID]
}
return tenantsForObjects, nil
}
// GetTenantForApplicationTemplate builds tenant with labels for application template
func (b *WebhookTenantBuilder) GetTenantForApplicationTemplate(ctx context.Context, tenant string, labels map[string]string) (*webhook.TenantWithLabels, error) {
if subaccountID, ok := labels[globalSubaccountIDLabelKey]; ok {
tenantModel, err := b.tenantRepository.GetByExternalTenant(ctx, subaccountID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant by external ID %q", subaccountID)
}
tenantLabels, err := b.labelInputBuilder.GetLabelsForObject(ctx, tenant, subaccountID, model.TenantLabelableObject)
if err != nil {
return nil, errors.Wrap(err, "while listing tenant labels")
}
return &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: tenantLabels,
}, nil
}
return nil, nil
}
// GetTenantsForObjects builds tenants with labels for objects of type runtime, runtime context or application
func (b *WebhookTenantBuilder) GetTenantsForObjects(ctx context.Context, tenant string, objectIDs []string, resourceType resource.Type) (map[string]*webhook.TenantWithLabels, error) {
tenantsForObjects := make(map[string]*webhook.TenantWithLabels)
tenantIDs := make([]string, 0)
tenantIDsMap := make(map[string]*model.BusinessTenantMapping)
objectTenantMapping := make(map[string]string)
for _, objectID := range objectIDs {
tenantID, err := b.tenantRepository.GetLowestOwnerForResource(ctx, resourceType, objectID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant for object with ID %q", objectID)
}
objectTenantMapping[objectID] = tenantID
// Check if we have loaded the tenant already, if so, no need for extra queries
if tenantModel, ok := tenantIDsMap[tenantID]; ok {
tenantsForObjects[objectID] = &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: nil,
}
continue
}
tenantModel, err := b.tenantRepository.Get(ctx, tenantID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant with ID %q", tenantID)
}
tenantsForObjects[objectID] = &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: nil,
}
tenantIDs = append(tenantIDs, tenantID)
tenantIDsMap[tenantID] = tenantModel
}
tenantLabels, err := b.labelInputBuilder.GetLabelsForObjects(ctx, tenant, tenantIDs, model.TenantLabelableObject)
if err != nil {
return nil, errors.Wrap(err, "while building tenant labels")
}
for _, objectID := range objectIDs {
tenantsForObjects[objectID].Labels = tenantLabels[objectTenantMapping[objectID]]
}
return tenantsForObjects, nil
}
// GetTenantForObject builds tenant with labels for object of type runtime, runtime context or application
func (b *WebhookTenantBuilder) GetTenantForObject(ctx context.Context, objectID string, resourceType resource.Type) (*webhook.TenantWithLabels, error) {
tenantID, err := b.tenantRepository.GetLowestOwnerForResource(ctx, resourceType, objectID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant lowest owner for object with id %q", objectID)
}
tenantModel, err := b.tenantRepository.Get(ctx, tenantID)
if err != nil {
return nil, errors.Wrapf(err, "while getting tenant for object with id %q", tenantID)
}
tenantLabels, err := b.labelInputBuilder.GetLabelsForObject(ctx, tenantID, tenantID, model.TenantLabelableObject)
if err != nil {
return nil, errors.Wrap(err, "while listing tenant labels")
}
return &webhook.TenantWithLabels{
BusinessTenantMapping: tenantModel,
Labels: tenantLabels,
}, nil
}