Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions cmd/ateapi/internal/apivalidation/actor_template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,48 @@ func TestValidateCreateActorTemplateRequest(t *testing.T) {
"valid",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate()},
nil,
}, {
"valid golden egress rules",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HTTPRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}}}
})},
nil,
}, {
"missing golden egress rules",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{}
})},
field.ErrorList{field.Required(field.NewPath("actor_template", "golden_egress_policy", "rules"), "")},
}, {
"empty golden egress rules",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{}}
})},
field.ErrorList{field.Required(field.NewPath("actor_template", "golden_egress_policy", "rules"), "")},
}, {
"invalid golden egress hostname",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Http: &ateapipb.HTTPRule{Hostnames: []string{"bad/host"}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}}}}
})},
field.ErrorList{field.Invalid(field.NewPath("actor_template", "golden_egress_policy", "rules").Index(0).Child("http", "hostnames").Index(0), nil, "")},
}, {
"golden egress rules tie across protocols",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{
{Https: &ateapipb.HTTPSRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}},
{TlsPassthrough: &ateapipb.TLSPassthroughRule{Hostnames: []string{"api.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}},
}}
})},
field.ErrorList{field.Invalid(field.NewPath("actor_template", "golden_egress_policy", "rules").Index(1).Child("tls_passthrough", "hostnames").Index(0), nil, "")},
}, {
"too many golden egress rules",
&ateapipb.CreateActorTemplateRequest{ActorTemplate: validActorTemplate(func(tmpl *ateapipb.ActorTemplate) {
tmpl.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{}
for i := range 257 {
tmpl.GoldenEgressPolicy.Rules = append(tmpl.GoldenEgressPolicy.Rules, &ateapipb.EgressRule{Http: &ateapipb.HTTPRule{Hostnames: []string{fmt.Sprintf("host-%d.example.com", i)}, Ports: &ateapipb.Ports{Numbers: []int32{80}}}})
}
})},
field.ErrorList{field.TooMany(field.NewPath("actor_template", "golden_egress_policy", "rules"), 257, 256).WithOrigin("maxItems")},
}, {
"missing actor_template",
&ateapipb.CreateActorTemplateRequest{},
Expand Down
4 changes: 4 additions & 0 deletions cmd/ateapi/internal/apivalidation/egress_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func ValidateCustom_EgressPolicy_Rules(_ context.Context, _ operation.Operation,

// ruleMatchFields is what a rule matches on: the union member, its hostnames,
// and its ports. Everything is empty for a rule that sets no member.
func ValidateCustom_EgressPolicyTemplate_Rules(ctx context.Context, op operation.Operation, p *field.Path, rules, oldRules []*ateapipb.EgressRule) field.ErrorList {
return ValidateCustom_EgressPolicy_Rules(ctx, op, p, rules, oldRules)
}

func ruleMatchFields(rule *ateapipb.EgressRule) (member string, hostnames []string, ports *ateapipb.Ports) {
switch {
case rule.GetHttp() != nil:
Expand Down
84 changes: 84 additions & 0 deletions cmd/ateapi/internal/apivalidation/zz_generated.validation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion cmd/ateapi/internal/controlapi/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,14 @@ func (s *ServiceImpl) CreateActor(ctx context.Context, inActor *ateapipb.Actor)
}

// Save the data in the storage layer.
stored, err := s.store.CreateActor(ctx, outActor)
var policy *ateapipb.EgressPolicy
if initial := template.GetGoldenEgressPolicy(); initial != nil && atespace == resources.GoldenActorAtespace {
policy = &ateapipb.EgressPolicy{
Metadata: &ateapipb.ResourceMetadata{Atespace: atespace, Name: "default"},
Rules: initial.GetRules(),
}
}
stored, err := s.store.CreateActor(ctx, outActor, policy)
if err != nil {
if errors.Is(err, store.ErrAlreadyExists) {
return nil, apierror.AlreadyExists("Actor %s already exists", name)
Expand Down
7 changes: 6 additions & 1 deletion cmd/ateapi/internal/controlapi/actor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"strings"
"testing"
Expand Down Expand Up @@ -673,7 +674,7 @@ func TestUpdateActor_DeleteRecreateRace(t *testing.T) {
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: testActorID},
ActorTemplate: &ateapipb.ObjectRef{Atespace: "ns1", Name: "tmpl1"},
Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_SUSPENDED},
})
}, nil)
if err != nil {
t.Fatalf("racing writer: recreate CreateActor: %v", err)
}
Expand Down Expand Up @@ -838,6 +839,7 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) {
}
if _, err := persistence.UpdateActorTemplate(ctx, resources.ActorTemplateRefFromActorTemplate(tmpl), store.PreconditionFrom(tmpl), func(db *ateapipb.ActorTemplate) error {
db.Status = &ateapipb.ActorTemplateStatus{GoldenSnapshotStatus: &ateapipb.GoldenSnapshotStatus{GoldenTag: ref}}
db.GoldenEgressPolicy = &ateapipb.EgressPolicyTemplate{Rules: []*ateapipb.EgressRule{{Https: &ateapipb.HTTPSRule{Hostnames: []string{"init.example.com"}, Ports: &ateapipb.Ports{Numbers: []int32{443}}}}}}
return nil
}); err != nil {
t.Fatal(err)
Expand All @@ -862,6 +864,9 @@ func TestCreateActor_GoldenTagDefault(t *testing.T) {
if got := created.GetStatus(); got.GetExternalSnapshot().GetSnapshotUri() != tag.GetStatus().GetSnapshot().GetSnapshotUri() || got.GetExternalSnapshot().GetActorTemplateUid() != tmpl.GetMetadata().GetUid() {
t.Fatalf("incorrect initial status: %v", got)
}
if _, err := persistence.GetEgressPolicy(ctx, resources.ActorRefFromActor(created)); !errors.Is(err, store.ErrNotFound) {
t.Fatalf("actor restored from a tag inherited golden policy: %v, want NotFound", err)
}
if scenario == "own snapshot" {
uri, err := resources.NewActorSnapshotURI(tmpl.GetSnapshotConfig().GetStorageLocation(), "team-a", created.GetMetadata().GetUid(), "snapshot")
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/ateapi/internal/controlapi/egress_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestActorEgressPolicy(t *testing.T) {
_, err := persistence.CreateActor(t.Context(), &ateapipb.Actor{
Metadata: &ateapipb.ResourceMetadata{Atespace: testAtespace, Name: "egress-actor"},
Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING},
})
}, nil)
if err != nil {
t.Fatal(err)
}
Expand Down
8 changes: 4 additions & 4 deletions cmd/ateapi/internal/controlapi/functionaltest/actor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ func TestDeleteActor_StateDeleting(t *testing.T) {
Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_DELETING},
ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"},
}
if _, err := tc.persistence.CreateActor(context.Background(), deletingActor); err != nil {
if _, err := tc.persistence.CreateActor(context.Background(), deletingActor, nil); err != nil {
t.Fatalf("CreateActor: %v", err)
}

Expand Down Expand Up @@ -1334,7 +1334,7 @@ func TestDeleteActor_WrongState(t *testing.T) {
Status: &ateapipb.ActorStatus{State: ateapipb.ActorState_ACTOR_STATE_RUNNING},
ActorTemplate: &ateapipb.ObjectRef{Atespace: testAtespace, Name: "tmpl1"},
}
if _, err := tc.persistence.CreateActor(context.Background(), runningActor); err != nil {
if _, err := tc.persistence.CreateActor(context.Background(), runningActor, nil); err != nil {
t.Fatalf("CreateActor: %v", err)
}

Expand Down Expand Up @@ -1379,7 +1379,7 @@ func TestDeleteActor_MultipleVolumeDeletionFailures(t *testing.T) {
},
},
}
if _, err := tc.persistence.CreateActor(context.Background(), actor); err != nil {
if _, err := tc.persistence.CreateActor(context.Background(), actor, nil); err != nil {
t.Fatalf("CreateActor: %v", err)
}

Expand Down Expand Up @@ -1454,7 +1454,7 @@ func TestDeleteActor_VolumeDeletionFailure_RetrySuccess(t *testing.T) {
},
},
}
if _, err := tc.persistence.CreateActor(context.Background(), actor); err != nil {
if _, err := tc.persistence.CreateActor(context.Background(), actor, nil); err != nil {
t.Fatalf("CreateActor: %v", err)
}

Expand Down
6 changes: 2 additions & 4 deletions cmd/ateapi/internal/controlapi/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import (
type RPCService struct {
ateapipb.UnimplementedControlServer
impl serviceStore
persistence serviceStore
workerCache *workercache.Cache
dialer *AteletDialer
sandboxConfigLister listersv1alpha1.SandboxConfigLister
Expand Down Expand Up @@ -91,7 +90,6 @@ func NewRPCService(
impl := newServiceImpl(persistence, storageClassLister)
s := &RPCService{
impl: impl,
persistence: persistence,
workerCache: workerCache,
sandboxConfigLister: sandboxConfigLister,
csiDriverConfigLister: csiDriverConfigLister,
Expand Down Expand Up @@ -166,7 +164,7 @@ func (s *RPCService) GetPlugin(ctx context.Context, driverName string) (volume.V
return csiPlugin, nil
}

// ServiceImpl implements store.Interface and provides the "middleware" layer
// ServiceImpl implements serviceStore and provides the "middleware" layer
// between the RPC and storage layers. It enforces invariants and validation
// rules, and may implement additional logic beyond the storage layer.
//
Expand All @@ -179,7 +177,7 @@ type ServiceImpl struct {
storageClassLister storagev1listers.StorageClassLister
}

var _ store.Interface = (*ServiceImpl)(nil)
var _ serviceStore = (*ServiceImpl)(nil)

// newServiceImpl creates an instance of the service's middleware
// implementation layer.
Expand Down
Loading
Loading