reading approvals from annotations
parent
8bff7f0c0f
commit
b913dcdde4
|
@ -40,16 +40,37 @@ func (p *Provider) updateComplete(plan *UpdatePlan) error {
|
|||
return p.approvalManager.Delete(getApprovalIdentifier(plan.Resource.Identifier, plan.NewVersion))
|
||||
}
|
||||
|
||||
func (p *Provider) isApproved(event *types.Event, plan *UpdatePlan) (bool, error) {
|
||||
labels := plan.Resource.GetLabels()
|
||||
func getInt(key string, labels map[string]string, annotations map[string]string) (int, error) {
|
||||
|
||||
minApprovalsStr, ok := labels[types.KeelMinimumApprovalsLabel]
|
||||
if !ok {
|
||||
// no approvals required - passing
|
||||
return true, nil
|
||||
var (
|
||||
valStr string
|
||||
ok bool
|
||||
)
|
||||
|
||||
valStr, ok = labels[key]
|
||||
if ok {
|
||||
valInt, err := strconv.Atoi(valStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return valInt, nil
|
||||
}
|
||||
|
||||
minApprovals, err := strconv.Atoi(minApprovalsStr)
|
||||
valStr, ok = annotations[key]
|
||||
if ok {
|
||||
valInt, err := strconv.Atoi(valStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return valInt, nil
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (p *Provider) isApproved(event *types.Event, plan *UpdatePlan) (bool, error) {
|
||||
|
||||
minApprovals, err := getInt(types.KeelMinimumApprovalsLabel, plan.Resource.GetLabels(), plan.Resource.GetAnnotations())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -58,15 +79,16 @@ func (p *Provider) isApproved(event *types.Event, plan *UpdatePlan) (bool, error
|
|||
return true, nil
|
||||
}
|
||||
|
||||
deadline := types.KeelApprovalDeadlineDefault
|
||||
|
||||
// deadline
|
||||
deadlineStr, ok := labels[types.KeelApprovalDeadlineLabel]
|
||||
if ok {
|
||||
d, err := strconv.Atoi(deadlineStr)
|
||||
if err == nil {
|
||||
deadline = d
|
||||
}
|
||||
deadline := types.KeelApprovalDeadlineDefault
|
||||
d, err := getInt(types.KeelApprovalDeadlineLabel, plan.Resource.GetLabels(), plan.Resource.GetAnnotations())
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"error": err,
|
||||
"resource": plan.Resource.GetName(),
|
||||
}).Warn("failed to parse approvals deadline, using default value")
|
||||
} else if d != 0 {
|
||||
deadline = d
|
||||
}
|
||||
|
||||
identifier := getApprovalIdentifier(plan.Resource.Identifier, plan.NewVersion)
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/keel-hq/keel/types"
|
||||
|
||||
apps_v1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -83,6 +83,88 @@ func TestCheckRequestedApproval(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCheckRequestedApprovalAnnotation(t *testing.T) {
|
||||
fp := &fakeImplementer{}
|
||||
fp.namespaces = &v1.NamespaceList{
|
||||
Items: []v1.Namespace{
|
||||
v1.Namespace{
|
||||
meta_v1.TypeMeta{},
|
||||
meta_v1.ObjectMeta{Name: "xxxx"},
|
||||
v1.NamespaceSpec{},
|
||||
v1.NamespaceStatus{},
|
||||
},
|
||||
},
|
||||
}
|
||||
deployments := []*apps_v1.Deployment{
|
||||
{
|
||||
meta_v1.TypeMeta{},
|
||||
meta_v1.ObjectMeta{
|
||||
Name: "dep-1",
|
||||
Namespace: "xxxx",
|
||||
Labels: map[string]string{},
|
||||
Annotations: map[string]string{
|
||||
types.KeelPolicyLabel: "all",
|
||||
types.KeelMinimumApprovalsLabel: "3",
|
||||
types.KeelApprovalDeadlineLabel: "20",
|
||||
},
|
||||
},
|
||||
apps_v1.DeploymentSpec{
|
||||
Template: v1.PodTemplateSpec{
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
v1.Container{
|
||||
Image: "gcr.io/v2-namespace/hello-world:1.1.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
apps_v1.DeploymentStatus{},
|
||||
},
|
||||
}
|
||||
|
||||
grs := MustParseGRS(deployments)
|
||||
grc := &k8s.GenericResourceCache{}
|
||||
grc.Add(grs...)
|
||||
|
||||
approver := approver()
|
||||
provider, err := NewProvider(fp, &fakeSender{}, approver, grc)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to get provider: %s", err)
|
||||
}
|
||||
// creating "new version" event
|
||||
repo := types.Repository{
|
||||
Name: "gcr.io/v2-namespace/hello-world",
|
||||
Tag: "1.1.2",
|
||||
}
|
||||
|
||||
deps, err := provider.processEvent(&types.Event{Repository: repo})
|
||||
if err != nil {
|
||||
t.Errorf("failed to get deployments: %s", err)
|
||||
}
|
||||
|
||||
if len(deps) != 0 {
|
||||
t.Errorf("expected to find 0 updated deployment but found %d", len(deps))
|
||||
}
|
||||
|
||||
// checking approvals
|
||||
approval, err := provider.approvalManager.Get("deployment/xxxx/dep-1:1.1.2")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to find approval, err: %s", err)
|
||||
}
|
||||
|
||||
if approval.Provider != types.ProviderTypeKubernetes {
|
||||
t.Errorf("wrong provider: %s", approval.Provider)
|
||||
}
|
||||
|
||||
if approval.VotesRequired != 3 {
|
||||
t.Errorf("expected 3 required votes, got: %d", approval.VotesRequired)
|
||||
}
|
||||
if approval.Deadline.Before(time.Now().Add(19 * time.Hour)) {
|
||||
t.Errorf("unexpected deadline: %s", approval.Deadline)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApprovedCheck(t *testing.T) {
|
||||
fp := &fakeImplementer{}
|
||||
fp.namespaces = &v1.NamespaceList{
|
||||
|
|
Loading…
Reference in New Issue