Skip to content

Commit c2536ed

Browse files
committed
wip
Signed-off-by: npolshakova <nina.polshakova@solo.io> wip Signed-off-by: npolshakova <nina.polshakova@solo.io> wip Signed-off-by: npolshakova <nina.polshakova@solo.io>
1 parent 6105286 commit c2536ed

20 files changed

Lines changed: 4562 additions & 156 deletions

File tree

.ko.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ defaultPlatforms:
2121
baseImageOverrides:
2222
github.com/agent-substrate/substrate/demos/sandbox: alpine
2323
github.com/agent-substrate/substrate/demos/agent-secret: alpine
24+
25+
x-agentgatewayEgressBaseImageOverrides:
26+
github.com/agent-substrate/substrate/cmd/ateom-gvisor: cr.agentgateway.dev/agentgateway:latest-dev

charts/substrate-crds/templates/ate.dev_actortemplates.yaml

Lines changed: 323 additions & 0 deletions
Large diffs are not rendered by default.

cmd/ateapi/internal/controlapi/workflow_suspend.go

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -141,29 +141,8 @@ func (s *CallAteletSuspendStep) Execute(ctx context.Context, input *SuspendInput
141141
ActorTemplateName: state.Actor.GetActorTemplateName(),
142142
ActorId: state.Actor.GetActorId(),
143143
Runsc: runscCfg,
144-
Spec: &ateletpb.WorkloadSpec{
145-
PauseImage: state.ActorTemplate.Spec.PauseImage,
146-
},
147-
SnapshotUriPrefix: state.Actor.GetInProgressSnapshot(),
148-
}
149-
for _, ctr := range state.ActorTemplate.Spec.Containers {
150-
ateletCtr := &ateletpb.Container{
151-
Name: ctr.Name,
152-
Image: ctr.Image,
153-
Command: ctr.Command,
154-
}
155-
for _, env := range ctr.Env {
156-
var val string
157-
if env.Value != nil {
158-
val = *env.Value
159-
}
160-
ateletEnv := &ateletpb.EnvEntry{
161-
Name: env.Name,
162-
Value: val,
163-
}
164-
ateletCtr.Env = append(ateletCtr.Env, ateletEnv)
165-
}
166-
req.Spec.Containers = append(req.Spec.Containers, ateletCtr)
144+
Spec: checkpointWorkloadSpecFromActorTemplate(state.ActorTemplate),
145+
SnapshotUriPrefix: state.Actor.GetInProgressSnapshot(),
167146
}
168147
_, err = client.Checkpoint(ctx, req)
169148
if err != nil {

cmd/ateapi/internal/controlapi/workload_spec.go

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const envSecretCacheTTL = 30 * time.Second
3434

3535
func workloadSpecFromActorTemplate(ctx context.Context, kubeClient kubernetes.Interface, secretCache *envSecretCache, actorTemplate *atev1alpha1.ActorTemplate) (*ateletpb.WorkloadSpec, error) {
3636
workloadSpec := &ateletpb.WorkloadSpec{
37-
PauseImage: actorTemplate.Spec.PauseImage,
37+
PauseImage: actorTemplate.Spec.PauseImage,
38+
EgressPolicy: buildAteletEgressPolicy(actorTemplate.Spec.EgressPolicy),
3839
}
3940
resolver := envResolver{
4041
kubeClient: kubeClient,
@@ -63,6 +64,123 @@ func workloadSpecFromActorTemplate(ctx context.Context, kubeClient kubernetes.In
6364
return workloadSpec, nil
6465
}
6566

67+
func checkpointWorkloadSpecFromActorTemplate(actorTemplate *atev1alpha1.ActorTemplate) *ateletpb.WorkloadSpec {
68+
workloadSpec := &ateletpb.WorkloadSpec{
69+
PauseImage: actorTemplate.Spec.PauseImage,
70+
EgressPolicy: buildAteletEgressPolicy(actorTemplate.Spec.EgressPolicy),
71+
}
72+
for _, ctr := range actorTemplate.Spec.Containers {
73+
ateletCtr := &ateletpb.Container{
74+
Name: ctr.Name,
75+
Image: ctr.Image,
76+
Command: ctr.Command,
77+
}
78+
for _, env := range ctr.Env {
79+
var val string
80+
if env.Value != nil {
81+
val = *env.Value
82+
}
83+
ateletCtr.Env = append(ateletCtr.Env, &ateletpb.EnvEntry{
84+
Name: env.Name,
85+
Value: val,
86+
})
87+
}
88+
workloadSpec.Containers = append(workloadSpec.Containers, ateletCtr)
89+
}
90+
return workloadSpec
91+
}
92+
93+
func buildAteletEgressPolicy(policy *atev1alpha1.EgressPolicy) *ateletpb.EgressPolicy {
94+
if policy == nil {
95+
return nil
96+
}
97+
return &ateletpb.EgressPolicy{
98+
DefaultAction: string(policy.DefaultAction),
99+
Allow: buildAteletEgressPolicyRules(policy.Allow),
100+
Deny: buildAteletEgressPolicyRules(policy.Deny),
101+
Audit: buildAteletEgressAuditPolicy(policy.Audit),
102+
}
103+
}
104+
105+
func buildAteletEgressAuditPolicy(policy *atev1alpha1.EgressAuditPolicy) *ateletpb.EgressAuditPolicy {
106+
if policy == nil {
107+
return nil
108+
}
109+
return &ateletpb.EgressAuditPolicy{
110+
Logs: policy.Logs,
111+
Traces: policy.Traces,
112+
RedactHeaders: append([]string(nil), policy.RedactHeaders...),
113+
}
114+
}
115+
116+
func buildAteletEgressPolicyRules(rules []atev1alpha1.EgressPolicyRule) []*ateletpb.EgressPolicyRule {
117+
out := make([]*ateletpb.EgressPolicyRule, 0, len(rules))
118+
for _, rule := range rules {
119+
outRule := &ateletpb.EgressPolicyRule{}
120+
for _, dest := range rule.To {
121+
outDest := &ateletpb.EgressPolicyDestination{Host: dest.Host}
122+
if dest.IPBlock != nil {
123+
outDest.Cidr = dest.IPBlock.CIDR
124+
}
125+
outRule.To = append(outRule.To, outDest)
126+
}
127+
for _, port := range rule.Ports {
128+
outRule.Ports = append(outRule.Ports, &ateletpb.EgressPort{
129+
Port: uint32(port.Port),
130+
Protocol: string(port.Protocol),
131+
})
132+
}
133+
outRule.Tls = buildAteletEgressTLSPolicy(rule.TLS)
134+
outRule.Credentials = buildAteletEgressCredentialPolicy(rule.Credentials)
135+
out = append(out, outRule)
136+
}
137+
return out
138+
}
139+
140+
func buildAteletEgressTLSPolicy(policy *atev1alpha1.EgressTLSPolicy) *ateletpb.EgressTLSPolicy {
141+
if policy == nil {
142+
return nil
143+
}
144+
out := &ateletpb.EgressTLSPolicy{
145+
Mode: string(policy.Mode),
146+
Required: policy.Required,
147+
}
148+
if policy.Intercept != nil {
149+
out.Intercept = &ateletpb.EgressTLSInterceptPolicy{
150+
ValidateUpstream: policy.Intercept.ValidateUpstream,
151+
}
152+
if policy.Intercept.IssuerSecretRef != nil {
153+
out.Intercept.IssuerSecretRef = &ateletpb.SecretReference{
154+
Name: policy.Intercept.IssuerSecretRef.Name,
155+
Namespace: policy.Intercept.IssuerSecretRef.Namespace,
156+
}
157+
}
158+
}
159+
return out
160+
}
161+
162+
func buildAteletEgressCredentialPolicy(policy *atev1alpha1.EgressCredentialPolicy) *ateletpb.EgressCredentialPolicy {
163+
if policy == nil {
164+
return nil
165+
}
166+
out := &ateletpb.EgressCredentialPolicy{}
167+
for _, injection := range policy.Inject {
168+
outInjection := &ateletpb.EgressCredentialInjection{
169+
Header: injection.Header,
170+
}
171+
if injection.ValueFrom.SecretKeyRef != nil {
172+
outInjection.ValueFrom = &ateletpb.EgressCredentialValueFrom{
173+
SecretKeyRef: &ateletpb.SecretKeySelector{
174+
Name: injection.ValueFrom.SecretKeyRef.Name,
175+
Key: injection.ValueFrom.SecretKeyRef.Key,
176+
},
177+
}
178+
}
179+
out.Inject = append(out.Inject, outInjection)
180+
}
181+
return out
182+
}
183+
66184
type envResolver struct {
67185
kubeClient kubernetes.Interface
68186
namespace string

cmd/atelet/main.go

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,13 +587,106 @@ func (s *AteomHerder) dialAteom(ctx context.Context, targetAteomUid string) (ate
587587
// buildAteomWorkloadSpec projects the atelet-facing workload spec onto
588588
// the ateom-facing one — currently just the container names.
589589
func buildAteomWorkloadSpec(spec *ateletpb.WorkloadSpec) *ateompb.WorkloadSpec {
590-
out := &ateompb.WorkloadSpec{}
590+
out := &ateompb.WorkloadSpec{
591+
EgressPolicy: buildAteomEgressPolicy(spec.GetEgressPolicy()),
592+
}
591593
for _, ctr := range spec.GetContainers() {
592594
out.Containers = append(out.Containers, &ateompb.Container{Name: ctr.GetName()})
593595
}
594596
return out
595597
}
596598

599+
func buildAteomEgressPolicy(policy *ateletpb.EgressPolicy) *ateompb.EgressPolicy {
600+
if policy == nil {
601+
return nil
602+
}
603+
return &ateompb.EgressPolicy{
604+
DefaultAction: policy.GetDefaultAction(),
605+
Allow: buildAteomEgressPolicyRules(policy.GetAllow()),
606+
Deny: buildAteomEgressPolicyRules(policy.GetDeny()),
607+
Audit: buildAteomEgressAuditPolicy(policy.GetAudit()),
608+
}
609+
}
610+
611+
func buildAteomEgressAuditPolicy(policy *ateletpb.EgressAuditPolicy) *ateompb.EgressAuditPolicy {
612+
if policy == nil {
613+
return nil
614+
}
615+
return &ateompb.EgressAuditPolicy{
616+
Logs: policy.GetLogs(),
617+
Traces: policy.GetTraces(),
618+
RedactHeaders: append([]string(nil), policy.GetRedactHeaders()...),
619+
}
620+
}
621+
622+
func buildAteomEgressPolicyRules(rules []*ateletpb.EgressPolicyRule) []*ateompb.EgressPolicyRule {
623+
out := make([]*ateompb.EgressPolicyRule, 0, len(rules))
624+
for _, rule := range rules {
625+
outRule := &ateompb.EgressPolicyRule{
626+
Tls: buildAteomEgressTLSPolicy(rule.GetTls()),
627+
Credentials: buildAteomEgressCredentialPolicy(rule.GetCredentials()),
628+
}
629+
for _, dest := range rule.GetTo() {
630+
outRule.To = append(outRule.To, &ateompb.EgressPolicyDestination{
631+
Host: dest.GetHost(),
632+
Cidr: dest.GetCidr(),
633+
})
634+
}
635+
for _, port := range rule.GetPorts() {
636+
outRule.Ports = append(outRule.Ports, &ateompb.EgressPort{
637+
Port: port.GetPort(),
638+
Protocol: port.GetProtocol(),
639+
})
640+
}
641+
out = append(out, outRule)
642+
}
643+
return out
644+
}
645+
646+
func buildAteomEgressTLSPolicy(policy *ateletpb.EgressTLSPolicy) *ateompb.EgressTLSPolicy {
647+
if policy == nil {
648+
return nil
649+
}
650+
out := &ateompb.EgressTLSPolicy{
651+
Mode: policy.GetMode(),
652+
Required: policy.GetRequired(),
653+
}
654+
if policy.GetIntercept() != nil {
655+
out.Intercept = &ateompb.EgressTLSInterceptPolicy{
656+
ValidateUpstream: policy.GetIntercept().GetValidateUpstream(),
657+
}
658+
if policy.GetIntercept().GetIssuerSecretRef() != nil {
659+
out.Intercept.IssuerSecretRef = &ateompb.SecretReference{
660+
Name: policy.GetIntercept().GetIssuerSecretRef().GetName(),
661+
Namespace: policy.GetIntercept().GetIssuerSecretRef().GetNamespace(),
662+
}
663+
}
664+
}
665+
return out
666+
}
667+
668+
func buildAteomEgressCredentialPolicy(policy *ateletpb.EgressCredentialPolicy) *ateompb.EgressCredentialPolicy {
669+
if policy == nil {
670+
return nil
671+
}
672+
out := &ateompb.EgressCredentialPolicy{}
673+
for _, injection := range policy.GetInject() {
674+
outInjection := &ateompb.EgressCredentialInjection{
675+
Header: injection.GetHeader(),
676+
}
677+
if injection.GetValueFrom().GetSecretKeyRef() != nil {
678+
outInjection.ValueFrom = &ateompb.EgressCredentialValueFrom{
679+
SecretKeyRef: &ateompb.SecretKeySelector{
680+
Name: injection.GetValueFrom().GetSecretKeyRef().GetName(),
681+
Key: injection.GetValueFrom().GetSecretKeyRef().GetKey(),
682+
},
683+
}
684+
}
685+
out.Inject = append(out.Inject, outInjection)
686+
}
687+
return out
688+
}
689+
597690
// uploadIfExists uploads a local file to GCS (zstd-compressed) only if
598691
// the file is present. Missing files are silently skipped — used for
599692
// optional checkpoint side-files (pages.img, pages_meta.img).

0 commit comments

Comments
 (0)