Monitord Acces Change

This commit is contained in:
mr
2026-05-27 16:09:45 +02:00
parent a9284314ef
commit 7c91a8b032
19 changed files with 2496 additions and 332 deletions
+146 -29
View File
@@ -4,12 +4,12 @@ import (
"encoding/json"
"fmt"
"os/exec"
"sort"
"strings"
"cloud.o-forge.io/core/oc-lib/config"
"cloud.o-forge.io/core/oc-lib/models/common/models"
"cloud.o-forge.io/core/oc-lib/models/resources"
"cloud.o-forge.io/core/oc-lib/models/resources/native_tools"
"cloud.o-forge.io/core/oc-lib/models/workflow"
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
"cloud.o-forge.io/core/oc-lib/tools"
)
@@ -48,6 +48,7 @@ func (c *Container) AddVolumeMount(volumeMount VolumeMount, volumes []VolumeMoun
type VolumeMount struct {
Name string `yaml:"name"`
MountPath string `yaml:"mountPath"`
ReadOnly bool `yaml:"readOnly,omitempty"`
Storage *resources.StorageResource `yaml:"-"`
IsReparted bool `yaml:"-"`
}
@@ -90,8 +91,8 @@ type Artifact struct {
}
type ArtifactRepositoryRef struct {
ConfigMap string `yaml:"configMap"`
Key string `yaml:"key"`
ConfigMap string `yaml:"configMap,omitempty"`
Key string `yaml:"key,omitempty"`
}
type InOut struct {
@@ -110,7 +111,7 @@ type Template struct {
NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
}
func (template *Template) CreateEventContainer(execution *workflow_execution.WorkflowExecution, nt *resources.NativeTool, dag *Dag) {
func (template *Template) CreateEventContainer(execution *workflow_execution.WorkflowExecution, id string, wf *workflow.Workflow, nt *resources.NativeTool, dag *Dag, natsURL string) {
container := Container{Image: "natsio/nats-box", ImagePullPolicy: "IfNotPresent"}
container.Command = []string{"sh", "-c"} // all is bash
@@ -139,12 +140,21 @@ func (template *Template) CreateEventContainer(execution *workflow_execution.Wor
cmd := exec.Command(
"nats",
"pub",
"--server", config.GetConfig().NATSUrl+":4222",
"--server", natsURL,
tools.WORKFLOW_EVENT.GenerateKey(),
string(payload),
)
for _, args := range cmd.Args {
container.Args = append(container.Args, args)
if len(wf.Args[id]) > 0 {
for _, args := range wf.Args[id] {
container.Args = append(container.Args, args)
}
} else {
for _, args := range cmd.Args {
container.Args = append(container.Args, args)
}
}
container.Args = []string{
strings.Join(container.Args, " "),
}
template.Container = container
}
@@ -152,7 +162,7 @@ func (template *Template) CreateEventContainer(execution *workflow_execution.Wor
}
}
func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecution, processing *resources.ProcessingResource, dag *Dag) {
func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecution, wf *workflow.Workflow, itemID string, processing *resources.ProcessingResource, dag *Dag) {
index := 0
if d, ok := exec.SelectedInstances[processing.GetID()]; ok {
index = d
@@ -162,40 +172,147 @@ func (template *Template) CreateContainer(exec *workflow_execution.WorkflowExecu
return
}
inst := instance.(*resources.ProcessingInstance)
container := Container{Image: inst.Access.Container.Image, ImagePullPolicy: "IfNotPresent"}
container := Container{
Image: inst.Access.Container.Image,
ImagePullPolicy: "IfNotPresent",
}
if container.Image == "" {
return
}
container.Command = []string{"sh", "-c"} // all is bash
for _, v := range inst.Env {
template.Inputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
for _, v := range processing.Env {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range inst.Inputs {
template.Inputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
for _, v := range wf.Env[itemID] {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range inst.Inputs {
template.Outputs.Parameters = append(template.Inputs.Parameters, Parameter{Name: v.Name})
for _, v := range processing.Inputs {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range wf.Inputs[itemID] {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range processing.Outputs {
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
Name: v.Name,
Value: v.Value,
})
}
for _, v := range wf.Outputs[itemID] {
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
Name: v.Name,
Value: v.Value,
})
}
cmd := strings.ReplaceAll(inst.Access.Container.Command, container.Image, "")
for _, a := range strings.Split(cmd, " ") {
container.Args = append(container.Args, template.ReplacePerEnv(a, inst.Env))
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
container.Args = append(container.Args, template.ReplacePerEnv(a, inst.Env))
if len(wf.Args[itemID]) > 0 {
for _, a := range wf.Args[itemID] {
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
} else {
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
}
container.Args = []string{strings.Join(container.Args, " ")}
template.Container = container
}
func (template *Template) ReplacePerEnv(arg string, envs []models.Param) string {
for _, v := range envs {
if v.Name != "" && strings.Contains(arg, v.Name) {
// CreateServiceContainer crée le container Argo pour un ServiceResource.
// Pour HOSTED, le container appelle le service distant (endpoint connu) ;
// pour DEPLOYMENT, le container EST le service à déployer.
// La logique de paramètres est identique à CreateContainer.
func (template *Template) CreateServiceContainer(exec *workflow_execution.WorkflowExecution, wf *workflow.Workflow, itemID string, service *resources.ServiceResource, dag *Dag) {
index := 0
if d, ok := exec.SelectedInstances[service.GetID()]; ok {
index = d
}
instance := service.GetSelectedInstance(&index)
if instance == nil {
return
}
inst := instance.(*resources.ServiceInstance)
if inst.Access == nil || inst.Access.Container == nil || inst.Access.Container.Image == "" {
return
}
container := Container{
Image: inst.Access.Container.Image,
ImagePullPolicy: "IfNotPresent",
}
container.Command = []string{"sh", "-c"}
for _, v := range service.Env {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range wf.Env[itemID] {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range service.Inputs {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range wf.Inputs[itemID] {
template.Inputs.Parameters = AppendParamIfAbsent(template.Inputs.Parameters, Parameter{Name: v.Name})
}
for _, v := range service.Outputs {
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
Name: v.Name,
Value: v.Value,
})
}
for _, v := range wf.Outputs[itemID] {
template.Outputs.Parameters = AppendParamIfAbsent(template.Outputs.Parameters, Parameter{
Name: v.Name,
Value: v.Value,
})
}
cmd := strings.ReplaceAll(inst.Access.Container.Command, container.Image, "")
for _, a := range strings.Split(cmd, " ") {
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
if len(wf.Args[itemID]) > 0 {
for _, a := range wf.Args[itemID] {
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
} else {
for _, a := range strings.Split(inst.Access.Container.Args, " ") {
container.Args = append(container.Args, template.ReplacePerEnv(a, template.Inputs.Parameters))
}
}
container.Args = []string{strings.Join(container.Args, " ")}
template.Container = container
}
// AppendParamIfAbsent ajoute p à params uniquement si aucun paramètre
// portant le même nom n'est déjà présent. Évite les doublons quand les
// variables sont définies à la fois sur le ProcessingResource et sur le
// Workflow (overrides).
func AppendParamIfAbsent(params []Parameter, p Parameter) []Parameter {
for _, existing := range params {
if existing.Name == p.Name {
return params
}
}
return append(params, p)
}
func (template *Template) ReplacePerEnv(arg string, envs []Parameter) string {
// Tri par longueur décroissante : les noms longs sont remplacés en premier
// pour éviter que $FOO matche à l'intérieur de $FOOBAR.
sorted := make([]Parameter, len(envs))
copy(sorted, envs)
sort.Slice(sorted, func(i, j int) bool {
return len(sorted[i].Name) > len(sorted[j].Name)
})
for _, v := range sorted {
needle := "$" + v.Name
if v.Name != "" && strings.Contains(arg, needle) {
value := "{{ inputs.parameters." + v.Name + " }}"
arg = strings.ReplaceAll(arg, v.Name, value)
arg = strings.ReplaceAll(arg, "$"+v.Name, value)
arg = strings.ReplaceAll(arg, "$", "")
arg = strings.ReplaceAll(arg, needle, value)
}
}
return arg
@@ -204,10 +321,10 @@ func (template *Template) ReplacePerEnv(arg string, envs []models.Param) string
// AddAdmiraltyAnnotations marque le template pour qu'Admiralty route le pod
// vers le cluster virtuel correspondant au peerId.
//
// - elect: "" déclenche le webhook Admiralty sur le pod créé par Argo.
// - nodeSelector cible le virtual node Admiralty dont le label
// multicluster.admiralty.io/cluster-name vaut peerId,
// ce qui contraint le scheduling au cluster distant.
// - elect: "" déclenche le webhook Admiralty sur le pod créé par Argo.
// - nodeSelector cible le virtual node Admiralty dont le label
// multicluster.admiralty.io/cluster-name vaut peerId,
// ce qui contraint le scheduling au cluster distant.
func (t *Template) AddAdmiraltyAnnotations(peerId string) {
if t.Metadata.Annotations == nil {
t.Metadata.Annotations = make(map[string]string)
+22 -7
View File
@@ -17,11 +17,26 @@ type VolumeSpec struct {
} `yaml:"resources"`
}
// ExistingVolume references a pre-provisioned PVC (created by oc-datacenter).
// Used in Workflow.Spec.ExistingVolumes (yaml: "volumes") instead of volumeClaimTemplates.
type ExistingVolume struct {
Name string `yaml:"name"`
PersistentVolumeClaim struct {
ClaimName string `yaml:"claimName"`
} `yaml:"persistentVolumeClaim"`
// PVCRef references a pre-provisioned PersistentVolumeClaim by name.
type PVCRef struct {
ClaimName string `yaml:"claimName"`
}
// SecretRef references a K8s Secret to mount as a volume.
type SecretRef struct {
SecretName string `yaml:"secretName"`
}
// EmptyDirRef declares an emptyDir volume. Set Medium to "Memory" for /dev/shm-style RAM backing.
type EmptyDirRef struct {
Medium string `yaml:"medium,omitempty"`
}
// ExistingVolume represents any volume mounted into an Argo workflow spec.
// Exactly one of PersistentVolumeClaim, Secret, or EmptyDir should be non-nil.
type ExistingVolume struct {
Name string `yaml:"name"`
PersistentVolumeClaim *PVCRef `yaml:"persistentVolumeClaim,omitempty"`
Secret *SecretRef `yaml:"secret,omitempty"`
EmptyDir *EmptyDirRef `yaml:"emptyDir,omitempty"`
}