Files
Assistant/cmd/commit-runtime/candidate_release_context.go
2026-08-31 16:28:57 +03:00

42 lines
1.8 KiB
Go

package main
import (
"fmt"
"os"
"git.cin.su/m/Assistant/contracts/capability"
"git.cin.su/m/Assistant/contracts/identity"
)
// candidateReleaseContextFromRuntime accepts only deployment-owned metadata.
// It never derives a candidate slot from an HTTP request or notification body.
func candidateReleaseContextFromRuntime() (*capability.CandidateReleaseContext, error) {
const prefix = "CANDIDATE_"
release := os.Getenv(prefix + "RELEASE_SET_ID")
if release == "" {
return nil, nil
}
context := &capability.CandidateReleaseContext{
ReleaseSetID: release,
Slot: os.Getenv(prefix + "SLOT"),
TaskID: os.Getenv(prefix + "TASK_ID"),
PrincipalID: identity.PrincipalID(os.Getenv(prefix + "PRINCIPAL_ID")),
CapabilityID: capability.CapabilityID(os.Getenv(prefix + "CAPABILITY_ID")),
ResourceScope: os.Getenv(prefix + "RESOURCE_SCOPE"),
Mode: capability.CandidateBindingMode(os.Getenv(prefix + "BINDING_MODE")),
TargetKind: os.Getenv(prefix + "TARGET_KIND"),
TargetRef: os.Getenv(prefix + "TARGET_REF"),
TargetDigest: os.Getenv(prefix + "TARGET_DIGEST"),
AuthorityGrantID: os.Getenv(prefix + "AUTHORITY_GRANT_ID"),
}
var revision int64
if _, err := fmt.Sscan(os.Getenv(prefix+"TASK_REVISION"), &revision); err != nil {
return nil, fmt.Errorf("candidate task revision: %w", err)
}
context.TaskRevision = revision
if context.Slot == "" || context.TaskID == "" || context.TaskRevision < 1 || context.PrincipalID == "" || context.CapabilityID == "" || context.ResourceScope == "" || context.Mode == "" || context.TargetKind == "" || context.TargetRef == "" || context.TargetDigest == "" || context.AuthorityGrantID == "" {
return nil, fmt.Errorf("incomplete candidate release metadata")
}
return context, nil
}