Skip to content

Commit 0775bd7

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 8070b02 commit 0775bd7

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
@@ -565,13 +565,106 @@ func (s *AteomHerder) dialAteom(ctx context.Context, targetAteomUid string) (ate
565565
// buildAteomWorkloadSpec projects the atelet-facing workload spec onto
566566
// the ateom-facing one — currently just the container names.
567567
func buildAteomWorkloadSpec(spec *ateletpb.WorkloadSpec) *ateompb.WorkloadSpec {
568-
out := &ateompb.WorkloadSpec{}
568+
out := &ateompb.WorkloadSpec{
569+
EgressPolicy: buildAteomEgressPolicy(spec.GetEgressPolicy()),
570+
}
569571
for _, ctr := range spec.GetContainers() {
570572
out.Containers = append(out.Containers, &ateompb.Container{Name: ctr.GetName()})
571573
}
572574
return out
573575
}
574576

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

0 commit comments

Comments
 (0)