-
Notifications
You must be signed in to change notification settings - Fork 84
/
is_not_assigned_to_any_formation_of_type_operator.go
101 lines (84 loc) · 3.56 KB
/
is_not_assigned_to_any_formation_of_type_operator.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
package operators
import (
"context"
"github.com/kyma-incubator/compass/components/director/internal/domain/label"
"github.com/kyma-incubator/compass/components/director/internal/model"
"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
"github.com/kyma-incubator/compass/components/director/pkg/formationconstraint"
"github.com/kyma-incubator/compass/components/director/pkg/log"
"github.com/pkg/errors"
)
const (
// IsNotAssignedToAnyFormationOfTypeOperator represents the IsNotAssignedToAnyFormationOfType operator
IsNotAssignedToAnyFormationOfTypeOperator = "IsNotAssignedToAnyFormationOfType"
)
// NewIsNotAssignedToAnyFormationOfTypeInput is input constructor for IsNotAssignedToAnyFormationOfType operator. It returns empty OperatorInput.
func NewIsNotAssignedToAnyFormationOfTypeInput() OperatorInput {
return &formationconstraint.IsNotAssignedToAnyFormationOfTypeInput{}
}
// IsNotAssignedToAnyFormationOfType is a constraint operator. It checks if the resource from the OperatorInput is already part of formation of the type that the operator is associated with
func (e *ConstraintEngine) IsNotAssignedToAnyFormationOfType(ctx context.Context, input OperatorInput) (bool, error) {
log.C(ctx).Infof("Executing operator: %s", IsNotAssignedToAnyFormationOfTypeOperator)
i, ok := input.(*formationconstraint.IsNotAssignedToAnyFormationOfTypeInput)
if !ok {
return false, errors.New("Incompatible input")
}
log.C(ctx).Infof("Enforcing %q constraint on resource of type: %q, subtype: %q and ID: %q", IsNotAssignedToAnyFormationOfTypeOperator, i.ResourceType, i.ResourceSubtype, i.ResourceID)
var assignedFormations []string
switch i.ResourceType {
case model.TenantResourceType:
tenantInternalID, err := e.tenantSvc.GetInternalTenant(ctx, i.ResourceID)
if err != nil {
return false, err
}
assignments, err := e.asaSvc.ListForTargetTenant(ctx, tenantInternalID)
if err != nil {
return false, err
}
assignedFormations = make([]string, 0, len(assignments))
for _, a := range assignments {
assignedFormations = append(assignedFormations, a.ScenarioName)
}
case model.ApplicationResourceType:
scenariosLabel, err := e.labelRepo.GetByKey(ctx, i.Tenant, model.ApplicationLabelableObject, i.ResourceID, model.ScenariosKey)
if err != nil {
if apperrors.IsNotFoundError(err) {
return true, nil
}
return false, err
}
assignedFormations, err = label.ValueToStringsSlice(scenariosLabel.Value)
if err != nil {
return false, err
}
default:
return false, errors.Errorf("Unsupported resource type %q", i.ResourceType)
}
isAllowedToParticipateInFormationsOfType, err := e.isAllowedToParticipateInFormationsOfType(ctx, assignedFormations, i.Tenant, i.FormationTemplateID, i.ResourceSubtype, i.ExceptSystemTypes)
if err != nil {
return false, err
}
return isAllowedToParticipateInFormationsOfType, nil
}
func (e *ConstraintEngine) isAllowedToParticipateInFormationsOfType(ctx context.Context, assignedFormationNames []string, tenant, formationTemplateID, resourceSubtype string, exceptSystemTypes []string) (bool, error) {
if len(assignedFormationNames) == 0 {
return true, nil
}
if len(exceptSystemTypes) > 0 {
for _, exceptType := range exceptSystemTypes {
if resourceSubtype == exceptType {
return true, nil
}
}
}
assignedFormations, err := e.formationRepo.ListByFormationNames(ctx, assignedFormationNames, tenant)
if err != nil {
return false, err
}
for _, formation := range assignedFormations {
if formation.FormationTemplateID == formationTemplateID {
return false, nil
}
}
return true, nil
}